C#Attachedchild任务永远不会执行

时间:2016-11-11 16:53:53

标签: c# multithreading task

我有两个任务需要同时执行,顶级任务在其子结束时结束。

对于更多背景,子任务执行冗长的查询,外部任务在UI上显示计数器(通过调用),以便用户知道发生了什么。子任务完成后,它会使用结果更新UI,此时不再需要计数器(父任务)。但是,当任务启动时,只启动父任务,子任务永远不会执行。顺便说一下,我没有使用BackgroundWorker,因为我需要能够同时执行多个查询/计数器。

任务以DataGridView中的click事件开始:

private void hostMgmtDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    var parent = Task.Factory.StartNew(() =>
    {
        showTimer(e.ColumnIndex, e.RowIndex, 0);
        var child = Task.Factory.StartNew(() =>
        {
            winUpdate(hostMgmtDataGridView.Rows[e.RowIndex].Cells[1].Value.ToString(), e.ColumnIndex, e.RowIndex);
        },TaskCreationOptions.AttachedToParent);
    });
}

此语法取自以下文章:https://msdn.microsoft.com/en-us/library/dd997417(v=vs.100).aspx

如果我添加parent.Wait();如上文所述,整个UI线程都会锁定,这不是理想的结果。

任何建议都将不胜感激。

修改 我尝试使用文章中的示例代码(对我的表单稍作调整):

var parent = Task.Factory.StartNew(() =>
{
    debugLabel1.Invoke(new Action(() => debugLabel1.Text = "parent starting"));

    var child = Task.Factory.StartNew(() =>
    {
        debugLabel2.Invoke(new Action(() => debugLabel2.Text = "child starting"));
        Thread.SpinWait(5000000);
        debugLabel2.Invoke(new Action(() => debugLabel2.Text = "child stopped"));
    },TaskCreationOptions.AttachedToParent);
});
parent.Wait();
debugLabel1.Text = "parent stopped";

如果我离开parent.Wait(),UI线程会再次锁定。如果我取出Wait语句,“parent stopped”永远不会显示,但“child stopped”会显示。

进一步阅读后,很多人建议使用“ContinueWith”,但我需要同时运行两个任务,Continuation按顺序运行任务。

1 个答案:

答案 0 :(得分:0)

您的锁定可能是由UI更改实现引起的。 我可以使用这个来完成相同的任务;

 var context = TaskScheduler.FromCurrentSynchronizationContext();
            var parent = Task.Factory.StartNew(() => {

            Task.Delay(40000);
                MessageBox.Show("From Parent");
            var child = Task.Factory.StartNew(() =>{
                MessageBox.Show("From Child");
                Task.Delay(30000);
                Text = "Title change from Child";
            });
            }, CancellationToken.None, TaskCreationOptions.AttachedToParent, context);

编辑:请参阅以下有关以下声明的Evk评论

此外,如果您使用的是框架4.5,我建议使用Task.Run而不是Task.Factory.StartNew ...有关详细信息,请参阅https://blogs.msdn.microsoft.com/pfxteam/2011/10/24/task-run-vs-task-factory-startnew/