TPL问题,错误处理和返回值

时间:2010-12-22 20:57:50

标签: c# task parallel-processing task-parallel-library

我正在努力实现这样的场景,但是输入参数和返回值。

这很好用,我得到了我的期望:

public class AsyncStuff2
{
    public void DoAsyncStuff()
    {            
        TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

        Task myTask = Task.Factory.StartNew(() =>
        {
            OperationXy();
        });

        bool hadError = false;

        myTask = myTask.ContinueWith(errorTest =>
        {
            Console.WriteLine("Faulted");
            hadError = true;

            if (errorTest.Exception != null)
            {
                Console.WriteLine(errorTest.Exception.Message);
            }
        }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler);

       myTask.ContinueWith(another =>
        {
            Console.WriteLine("Done");

            if (hadError)
            {
                Console.WriteLine("...but with error");
            }

        }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, uiScheduler);

    }

    private void OperationXy()
    {
        Console.WriteLine("OperationXY");
        throw new ArgumentException("Just for Test");
    }

输出将是:

OperationXY 断陷 发生了一个或多个错误。 完成 ......但有错误

但是当我修改这个例子时,任务继续不再像我一样工作了:

public class AsyncStuff
{

    public string Path { get; set; }

    public void DoAsyncStuff()
    {
        Path = "A Input...";

        TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

        Task<string> myTask = Task<string>.Factory.StartNew((input) =>
        {
            return OperationXy(Path);

        }, Path, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);

        bool hadError = false;

        myTask = myTask.ContinueWith<string>(errorTest =>
        {
            Console.WriteLine("Faulted");
            hadError = true;

            if (errorTest.Exception != null)
            {
                Console.WriteLine(errorTest.Exception.Message);
            }

            return null;

        }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler);

        myTask.ContinueWith(another =>
        {
            Console.WriteLine("Done, Result: {0}", myTask.Result);

            if (hadError)
            {
                Console.WriteLine("...but with error");
            }

        }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, uiScheduler);
    }

    private string OperationXy(string returnThat)
    {
        Console.WriteLine("OperationXY, Input ({0})", returnThat);

        //throw new ArgumentException("Just for Test");

        return returnThat;
    }

}

我想要实现的目标是:

  • 将处理所需的输入传递给任务
  • 将结果设置为UI元素
  • 处理错误,但仍然继续“OnlyOnRanToCompletion”

任何帮助表示赞赏

由于

马丁

1 个答案:

答案 0 :(得分:1)

这是因为您的代码中存在错误。您在创建错误处理延续时重新定义myTask。这一行:

        myTask = myTask.ContinueWith(errorTest =>

应阅读:

        myTask.ContinueWith(errorTest =>

否则,您将向错误处理延续添加run to completion continuation,而不是原始myTask。

这应该修复你的代码。输出现在应该是:

OperationXY 
Done