跨线程调用问题

yunhaiC QQ654777694 2014-11-08 01:48:47

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public delegate void GUIDelegate(string paramString);
BackgroundWorker bgw = new BackgroundWorker();

private void button1_Click(object sender, EventArgs e)
{
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.WorkerSupportsCancellation = true;
bgw.RunWorkerAsync();

}

void bgw_DoWork(object sender, DoWorkEventArgs e)
{
while (!bgw.CancellationPending)
{
DoGUIUpdate((i++).ToString());
System.Threading.Thread.Sleep(1000);
}
}

int i = 0;

public void DoGUIUpdate(string paramString)
{
if (this.InvokeRequired)
{
GUIDelegate delegateMethod = new GUIDelegate(DoGUIUpdate);
this.Invoke(delegateMethod, new object[] { paramString });
}
else
{
listBox1.Items.Add("the count is:" + paramString);
}
}
}
}
我有点不太明白,backgroundworker算是建立了一个线程,这个时候去调用窗口上空间的线程,于是this.InvokeRequired等于true,就开始执行this.Invoke,但是他怎么执行到listBox1.Items.Add("the count is:" + paramString);这一行的,不是太明白,而且好像这样的程序没办法debug。
总结就是2个问题:
1.他怎么执行到listBox1.Items.Add("the count is:" + paramString);这一行的
2.这样的程序如何debug

...全文
156 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xian_wwq 2014-11-17
  • 打赏
  • 举报
回复
backgroundWorker本身是为了简化跨线程处理 用了backgroundWorker就可以不用委托 否则直接起线程,使用委托,抛开backgroundWorker
willhuo 2014-11-17
  • 打赏
  • 举报
回复
我怎么赶脚你的代码有点混乱呢,如果你想用backgroundworkder的话,可以直接完全按照backgroundworker的方法来做,这个是支持控件操作的,直接拖拽即可 至于更新listview,你可以在do_work里边执行完了以后,用传递参数的办法传递到相应的 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)来操作 UI线程和backgroundworder线程一般不建议直接进行数据交互,最好做一个托管,例如 backgroundWorker1_ProgressChanged

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            //具体操作
            webBrowser1.Navigate("http://www.baidu.com");
            backgroundWorker2.ReportProgress(0,string.Format("{0}","可以是listview需要操作的地方"));
        }

        private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //线程交互,可以对UI进行处理,数据来自e.userstata as object (你想转换的数据类型)
            string s = e.UserState.ToString();
        }

        private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //线程执行完成后的操作
        }
於黾 2014-11-17
  • 打赏
  • 举报
回复
DoGUIUpdate这个函数,不就是个递归调用吗 第一次调用,是在线程中,然后判断非UI线程,于是用委托再次执行自身 再次执行时,是在UI线程里调用,于是进入else 你说无法加断点,你把断点加到哪里了?
猴子写代码 2014-11-16
  • 打赏
  • 举报
回复
你这句话不就是控制线程安全吗,listBox1.Items.Add("the count is:" + paramString);这句话只有ui线程才能调用的
  • 打赏
  • 举报
回复
断点好像是不行的,你们试试,我确实试了
江南小鱼 2014-11-08
  • 打赏
  • 举报
回复
1、this.InvokeRequired,说白了就是判断当前线程是否为UI线程,如果不是UI线程(this.InvokeRequired = true),需要通过this.Invoke去调用窗体控件(给listbox1添加Item),否则可以直接操作窗体控件。 2、打断点,单步调试有什么问题吗?
  • 打赏
  • 举报
回复
两个问题其实是同一个问题:你真的执行不了单步调试吗?

110,532

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧