我想更新标签并从后台工作人员中删除网格中的一行。我当时正在报告进度,但是我发现报告进度事件没有立即触发,并发现我的第二个报告进度是在处理第一个事件之前执行的。
为了等待事件触发,我想到了使用自动重置事件来暂停执行(等待),而progress事件将其设置为让后台工作程序继续执行。
然后我想知道事件是否有可能在侍应生之前触发。
处理此问题的最佳方法是什么? 编辑:根据帕特里克·图奇(Patrick Tucci)的建议,我发现了以下链接... https://social.msdn.microsoft.com/Forums/en-US/cbd99f1f-ac56-440b-8fbd-093534e11d69/how-do-i-update-the-gui-during-execution-of-a-task?forum=csharpgeneral 在该链接中是这段代码(我做了一些修改)...
private void button1_Click(object sender, EventArgs e)
{
var uiContext = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();
// Start a task - this runs on the background thread...
System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
for (int i = 1; i < 5; i++)
{
Console.WriteLine("A i is " + i.ToString());
System.Threading.Thread.Sleep(2000);
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
Console.WriteLine("B i is " + i.ToString());
textBox1.Text = "Delay " + i.ToString() + " has completed";
}, System.Threading.CancellationToken.None, System.Threading.Tasks.TaskCreationOptions.None, uiContext);
//textBox1.Text = "Delay " + i.ToString() + " has completed";
}
}, );
MessageBox.Show("boom!");
}
但是,以上内容对我来说还是不清楚的... 为什么第一个Task.Factory.StartNew被认为是后台任务? 消息框语句(轰)立即触发。有没有办法在异步任务完成之前不继续? 并且,由于某种原因,从不显示“延迟1”,即未将A2打印到调试控制台:仅显示A1 B1 B2 C1 C2等?
答案 0 :(得分:0)
好的,这是我的失败,无法理解autoresetevent的工作原理。
在后台工作程序中的循环开始之前,我仍然应该 AE.Reset 。这样做意味着下一个 WaitOne 将使工作人员入睡。
在循环中,我应该照常 ReportProgress ,然后是 WaitOne 。 WaitOne 使工作人员进入睡眠状态,但前提是AE已重置。如果AE已设置,则工作人员将照常继续操作。
在 ProgressChanged 事件中,我应该更新常规的Gui控件,然后更新 AE.Set ,以便允许处于睡眠状态的工人在 WaitOne >状态以继续。
如果出于某种原因在 AE.Set 之后执行了 AE.WaitOne ,则工作人员不会等待任何事情。
最后,无论工人是否等待,AE都会自动重置,这意味着 WaitOne 将再次进入睡眠状态。
基本上... 进行重置会使下一个 WaitOne 进入睡眠状态。 进行设置会释放 WaitOne 中的线程。 如果 WaitOne 中没有任何内容,Set会立即释放 NEXT WaitOne 。 自动重置。
WaitOne
。有点令人困惑,文档也不是最好的。但是我明白了。
我会坚持做后台工作人员,因为我认为它们是更简单的任务。