任务不等待ContinueWith完成

时间:2014-05-30 10:44:13

标签: c# task

我有控制台应用程序和代码,如下所示,

我的问题是在ContinueWith任务完成之前,控制台应用程序结束,它没有等待continueWith完成,请指教。

请让我知道我遗失或不正确的内容。

var task1 = Task<bool>.Factory.StartNew(() => DoProcess());

task1 .ContinueWith(
     t1 => updateSuccess(),
       TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.ExecuteSynchronously);

task1 .ContinueWith(
     t => updateFault(),
     TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);

task1.Wait();

3 个答案:

答案 0 :(得分:5)

您必须wait完成从主线程完成的任务。简化它看起来像

var task1 = Task<bool>.Factory.StartNew(() => DoProcess());

successContinuation = task1 .ContinueWith(t1 => updateSuccess(),
                                          TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.ExecuteSynchronously)
failureContinuation = task1 .ContinueWith( t => updateFault(),
                                          TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);

Task.WaitAny(successContinuation, failureContinuation);

我认为你没有意识到你正在创建一个(实际上只是可能)在不同的线程中执行的任务。一旦你开始你的任务,你有两个不同的执行线程,主线程将继续运行,你的任务。如果您希望主线程(控制台应用程序)等待任务完成,则必须手动指定它。

答案 1 :(得分:1)

当抛出异常时,Jorge的解决方案无效:

var task = new Task(() =>
    {
        Console.WriteLine("My task...");
        throw new Exception();
    });

task.Start();

var taskNotOnFaulted = task.ContinueWith(t =>
{
    Thread.Sleep(1000);
    Console.WriteLine("NotOnFaulted");
}, TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
var taskOnlyOnFaulted = task.ContinueWith(t =>
{
    Thread.Sleep(1000);
    Console.Write("OnlyOnFaulted");
}, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);

Task.WaitAny(taskNotOnFaulted, taskOnlyOnFaulted);

Console.WriteLine("Finished");

输出结果为:

My task...
Finished
OnlyOnFaulted

这是因为taskNotOnFaulted在抛出异常时获得Canceled状态,而在没有抛出异常时它保持WaitingForActivation状态。

所以你必须更换:

Task.WaitAny(taskNotOnFaulted, taskOnlyOnFaulted);

通过

if (task.IsFaulted)
    taskOnlyOnFaulted.Wait();
else
    taskNotOnFaulted.Wait();

答案 2 :(得分:0)

我尝试了另一种对我有用的解决方案:

try {
    taskNotOnFaulted.Wait();
} catch {
    taskOnlyOnFaulted.Wait();
}