从backgroundworker更新表单

时间:2019-05-04 12:34:02

标签: c# backgroundworker autoresetevent

我想更新标签并从后台工作人员中删除网格中的一行。我当时正在报告进度,但是我发现报告进度事件没有立即触发,并发现我的第二个报告进度是在处理第一个事件之前执行的。

为了等待事件触发,我想到了使用自动重置事件来暂停执行(等待),而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等?

1 个答案:

答案 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

有点令人困惑,文档也不是最好的。但是我明白了。

我会坚持做后台工作人员,因为我认为它们是更简单的任务。