我有两个任务需要同时执行,顶级任务在其子结束时结束。
对于更多背景,子任务执行冗长的查询,外部任务在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按顺序运行任务。
答案 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/