【发布时间】:2016-10-24 19:43:33
【问题描述】:
使用 .NET4、c#、 我在winform上有一个网格。当我点击一个进程按钮时,我需要对每一行执行几个步骤的及时操作,然后用结果更新该行。这样,用户可以在处理下一行时看到进度。如果用户点击取消或关闭表单,我需要完成当前行的过程,然后中断或关闭表单。根据我的研究,这是我想出的。我还有 2 个问题。
这是我的代码:
delegate void OperateGridMethodDelegate();
delegate void UpdateProgressDelegate(int rowIndex, string msg);
bool isCancelled = false;
private void ButtonOne_Click(object sender, EventArgs e)
{
isCancelled=false;
OperateGridMethodDelegate delegate = new OperateGridMethodDelegate(LongProcess);`
delegate.BeginInvoke(null,null);
}
private void ButtonTow_Click(object sender, EventArgs e)
{
MyButtonOne.Enabled=false;
isCancelled=true;
}
private void LongProcess()
{
foreach (DataRow row in dataTableOne.Rows)
{
//Do Lengthy Process
DisplayResult( rowIndex, "this is result of operation" );
if(isCancelled)
{
MyButtonOne.Enabled=true;
break;
}
}
}
private void DisplayResult(int rowIndex,string message)
{
if(myGrid.InvokeRequired == false)
{
myGrid.Rows[rowIndex].value = message;
}
else
{
UpdateProgressDelegate delegate = new UpdateProgressDelegate(DisplayResult);
myGrid.BeginInvoke(delegate, new object[] { rowIndex, message });
}
}
我剩下的两个问题是:
当表单关闭时,我想等待 LongProcess(由我的 OperateGridMethodDelegate 调用)完成它的行,然后取消(与 ButtonTwo 一样),但我可以'让这个工作。
我在调试时注意到一个奇怪的行为,我不确定这是一个错误还是正确的,当一行完成处理时,结果没有设置。相反,处理下一行,然后显示上一行结果。当第三行结束时显示第二行结果等。然后最后两行结果基本同时显示。
我的方法正确吗?
【问题讨论】:
-
不要使用委托的 BeginInvoke() 方法来实现线程,bool 不是同步原语。有更好的方法可以做到这一点,this Q+A 中介绍了如何正确处理 BackgroundWorker。
标签: c# multithreading asynchronous invoke begininvoke