积极答复者
backgroundwork的问题,死活搞不定了。求助

问题
-
[C#.NET] 如何 使用 BackgroundWorker 多執行緒 / 跨執行緒 存取UI http://www.dotblogs.com.tw/yc421206/archive/2009/02/15/7174.aspx
我看这个文章,没看懂。。
照样做了,但是运行不了。代码如下:
int icount = 100000;
string mystr;private delegate void myUICallBack(string mystr, Control ctl);
private void myUI(string mystr, Control ctl)
{
if (this.InvokeRequired)
{
myUICallBack myUpdate = new myUICallBack(myUI);
this.Invoke(myUpdate, mystr, ctl);
}
else
{
ctl.Text = mystr;
}
}
C#初学者,所以提的问题对各位前辈朋友来说可能很简单,也可能问法也不对,非常期待大家的回答……
答案
-
你好
icount 只是一個optional Parameter 用來給 你 的
for (int i = 1; i <= icount; i++) 使用的
有關 使用 多執行緒 或者你可以參考以下URL
VB.Net Use BackgroundWorker To Improved User Experience — VB.Net 使用 BackgroundWorker 增加使用者經驗上
VB.Net Threading —VB.Net 線程
http://blog.sharechiwai.com/2010/09/vb-net-threading-vb-net-%E7%B7%9A%E7%A8%8B/
Please correct me if my concept is wrong
Chi- 已标记为答案 永远的小六 2010年11月25日 2:22
-
dear
你说会失败的原因是UI卡住吗??如果是的话,原因是回报状态(backgroundWorker1_ProgressChanged)方法跟runsample方法暫停的时间一样,所以视觉上会觉得UI卡住,你可参考以下。
1.runsample方法占停的时间要大于回报状态(backgroundWorker1_ProgressChanged),下面两行顺序最好不要调换。
Application.DoEvents();
Thread.Sleep(2);private void runsample(BackgroundWorker mywork) { mystr = ""; for (int i = 1; i <= icount; i++) { try { mywork.ReportProgress(i); mystr = i.ToString(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); break; } } Application.DoEvents(); Thread.Sleep(2); }
2.把回报回报状态(backgroundWorker1_ProgressChanged)的占停Thread.Sleep(1);拿掉
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { try { this.progressBar1.Value = e.ProgressPercentage; //Thread.Sleep(1); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
以上选一种来跑跑看
秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/- 已标记为答案 永远的小六 2010年11月25日 2:22
-
首先理清backgroudWorker1是怎么工作的。
我觉得backgroudWorker是为了简化多线程的代码量而存在的一个控件,因为他只有三个Event处理函数,只要理解了原理就很容易使用
1,private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
这个函数里面的所有动作,都是在单独一个线程里面执行的,是你真正想要做的处理。
从这里面不能修改主线程界面。但是在这里可以调用backgroundWorker1.ReportProgress(百分比,具体信息)函数,把要在界面上显示的东西传送给第二个Event处理函数。
2,private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
这个函数里面可以接收到上面ReportProgress()函数传送过来的百分比值和具体信息,显示在主界面上。
除了ProgressBar之外,修改其他控件的值(比如用一个主界面上的Label显示信息),应该用delegate 。
3,private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
DoWork()结束之后,就进入这个函数,你可以做一些弹出Message或者关闭画面之类的处理。
下面的两个属性设置,都不应该在DoWork里面做
this.backgroundWorker1.WorkerReportsProgress = true;
this.progressBar1.Maximum = icount;
应该在设置完这些属性之后,再调用backgroundWorker1.RunWorkerAsync(),告诉backgroundWorker1,你可以开始执行DoWork()处理了
格式有点乱,请凑合看吧:)
- 已标记为答案 永远的小六 2010年11月25日 2:22
-
dear,
1.你抄范例程式时有注册事件吗?
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
2.使用backgroundWorker若会发生跨执行绪的问题,表示WorkerReportsProgress未设定为true,你观察你的mywork的WorkerReportsProgress应该是false,所以只要在传入runsample()前设定为true就好了,变更顺序试试
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { this.backgroundWorker1.WorkerReportsProgress = true; this.progressBar1.Maximum = icount; runsample(sender as BackgroundWorker); }
秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/- 已标记为答案 永远的小六 2010年11月25日 2:21
全部回复
-
private void runsample(BackgroundWorker mywork)
{
mystr = "";
for (int i = 1; i <= icount; i++)
{
try
{
mywork.ReportProgress(i);
mystr = i.ToString();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
break;
}
}
Thread.Sleep(1);
Application.DoEvents();
}
C#初学者,所以提的问题对各位前辈朋友来说可能很简单,也可能问法也不对,非常期待大家的回答…… -
-
你好
icount 只是一個optional Parameter 用來給 你 的
for (int i = 1; i <= icount; i++) 使用的
有關 使用 多執行緒 或者你可以參考以下URL
VB.Net Use BackgroundWorker To Improved User Experience — VB.Net 使用 BackgroundWorker 增加使用者經驗上
VB.Net Threading —VB.Net 線程
http://blog.sharechiwai.com/2010/09/vb-net-threading-vb-net-%E7%B7%9A%E7%A8%8B/
Please correct me if my concept is wrong
Chi- 已标记为答案 永远的小六 2010年11月25日 2:22
-
你好
icount 只是一個optional Parameter 用來給 你 的
for (int i = 1; i <= icount; i++) 使用的
有關 使用 多執行緒 或者你可以參考以下URL
VB.Net Use BackgroundWorker To Improved User Experience — VB.Net 使用 BackgroundWorker 增加使用者經驗上
VB.Net Threading —VB.Net 線程
http://blog.sharechiwai.com/2010/09/vb-net-threading-vb-net-%E7%B7%9A%E7%A8%8B/
Please correct me if my concept is wrong
Chi
C#初学者,所以提的问题对各位前辈朋友来说可能很简单,也可能问法也不对,非常期待大家的回答…… -
dear
你说会失败的原因是UI卡住吗??如果是的话,原因是回报状态(backgroundWorker1_ProgressChanged)方法跟runsample方法暫停的时间一样,所以视觉上会觉得UI卡住,你可参考以下。
1.runsample方法占停的时间要大于回报状态(backgroundWorker1_ProgressChanged),下面两行顺序最好不要调换。
Application.DoEvents();
Thread.Sleep(2);private void runsample(BackgroundWorker mywork) { mystr = ""; for (int i = 1; i <= icount; i++) { try { mywork.ReportProgress(i); mystr = i.ToString(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); break; } } Application.DoEvents(); Thread.Sleep(2); }
2.把回报回报状态(backgroundWorker1_ProgressChanged)的占停Thread.Sleep(1);拿掉
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { try { this.progressBar1.Value = e.ProgressPercentage; //Thread.Sleep(1); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
以上选一种来跑跑看
秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/- 已标记为答案 永远的小六 2010年11月25日 2:22
-
首先理清backgroudWorker1是怎么工作的。
我觉得backgroudWorker是为了简化多线程的代码量而存在的一个控件,因为他只有三个Event处理函数,只要理解了原理就很容易使用
1,private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
这个函数里面的所有动作,都是在单独一个线程里面执行的,是你真正想要做的处理。
从这里面不能修改主线程界面。但是在这里可以调用backgroundWorker1.ReportProgress(百分比,具体信息)函数,把要在界面上显示的东西传送给第二个Event处理函数。
2,private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
这个函数里面可以接收到上面ReportProgress()函数传送过来的百分比值和具体信息,显示在主界面上。
除了ProgressBar之外,修改其他控件的值(比如用一个主界面上的Label显示信息),应该用delegate 。
3,private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
DoWork()结束之后,就进入这个函数,你可以做一些弹出Message或者关闭画面之类的处理。
下面的两个属性设置,都不应该在DoWork里面做
this.backgroundWorker1.WorkerReportsProgress = true;
this.progressBar1.Maximum = icount;
应该在设置完这些属性之后,再调用backgroundWorker1.RunWorkerAsync(),告诉backgroundWorker1,你可以开始执行DoWork()处理了
格式有点乱,请凑合看吧:)
- 已标记为答案 永远的小六 2010年11月25日 2:22
-
感谢cs.liwei
this.backgroundWorker1.WorkerReportsProgress = true;
this.progressBar1.Maximum = icount;
这两个为什么不能放这里啊?不解。this.backgroundWorker1.WorkerReportsProgress = true; 这个backgroundworker 的属性里直接设置, 但是 下面那个 this.progressBar1.Maximum = icount;如果icount是动态生成的话,另外好像没地方放啊
C#初学者,所以提的问题对各位前辈朋友来说可能很简单,也可能问法也不对,非常期待大家的回答…… -
dear,
1.你抄范例程式时有注册事件吗?
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
2.使用backgroundWorker若会发生跨执行绪的问题,表示WorkerReportsProgress未设定为true,你观察你的mywork的WorkerReportsProgress应该是false,所以只要在传入runsample()前设定为true就好了,变更顺序试试
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { this.backgroundWorker1.WorkerReportsProgress = true; this.progressBar1.Maximum = icount; runsample(sender as BackgroundWorker); }
秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/- 已标记为答案 永远的小六 2010年11月25日 2:21