【问题标题】:Multiple task execution多任务执行
【发布时间】:2018-08-01 14:17:25
【问题描述】:

我遇到了关于执行以下方法的问题。主要目的是这两个任务应该顺序执行。但是当我执行这个方法时,我得到 System.AggregateException。

 public Task<StockOptionData> GetOptionDataAsync(Stream str, Stock stck)
    {
        Task<StockOptionData> res; //second task /result task 
        Task<string> text; // first task 
        using (StreamReader reader = new StreamReader(str))
        {
            // Part 1 
            text = reader.ReadToEndAsync();
        }

       // Part  2
        res = text.ContinueWith((i) =>
            {
                JavaScriptSerializer ser = new JavaScriptSerializer();
                FullStockInfo info = ser.Deserialize<FullStockInfo>(i.Result);


                StockOptionData datas = new StockOptionData(info);
                return datas;
            });

        return res;

    }

有错误:

System.Reflection.TargetInvocationException:调用的目标已抛出异常。 ---> System.AggregateException:发生一个或多个错误。 ---> System.ObjectDisposedException:无法访问已处置的对象。 对象名称:'SslStream'。 在 System.Net.ConnectStream.EndRead(IAsyncResult asyncResult) 在 System.IO.Stream.c.b__43_1(流流,IAsyncResult asyncResult) 在 System.Threading.Tasks.TaskFactory1.FromAsyncTrimPromise1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization) --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) ...

仅当我使用此方法的异步版本时才发生异常。单胎面执行正常。问题是,我的错误在哪里?顺序执行具有不同结果的多个任务的最佳方法是什么?

【问题讨论】:

  • 读取数据时为什么没有在阅读器上调用await
  • 为什么你使用ContinueWith() 而不是仅仅使用await?你的代码是不必要的复杂,没有任何好处。
  • 看起来您将 ObjectDisposedException 作为内部异常,这意味着您在任务开始之前处置了阅读器。任务不保证立即启动。

标签: c# multithreading


【解决方案1】:

更简单明了。

你使用awaitTask等待读取操作完成。完成后,代码继续运行Deserialize

public async Task<StockOptionData> GetOptionDataAsync(Stream str, Stock stck)
{
    string myTextString  = "";
    using (StreamReader reader = new StreamReader(str))
    {
        myTextString = await reader.ReadToEndAsync();
    }

    JavaScriptSerializer ser = new JavaScriptSerializer();
    FullStockInfo info = ser.Deserialize<FullStockInfo>(myTextString);
    StockOptionData datas = new StockOptionData(info);
    return datas;
}

这是一个example如何顺序执行任务列表

【讨论】:

  • myTextString 范围在 using 块的右括号结束。
  • 我更喜欢这个解决方案,但是除非用户在方法签名中添加async关键字,否则它不会起作用。
  • 答题完毕
  • 这些反序列化代码运行同步。这意味着:无论有没有Task,你无论如何都必须等待他的执行。那么为什么我们需要将它们放在 Task 中呢?
  • 代码有效。但问题是一般来说,如何顺序执行两个或多个异步任务。这就是我在另一个任务中创建 Part2 的原因。
【解决方案2】:

简短的回答是这个方法不是异步的。尝试将async 关键字添加到方法和await 任何异步操作。

请参阅 Thierry V 的实施答案...

【讨论】:

  • @xxbbcc:我同意这个评估,但我只是给用户一个“简短的回答”。
  • @xxbbcc 等待 reader.ReadToEndAsync();返回一个string。一个字符串怎么可能 ContinueWith ?
  • 文本 = 等待 reader.ReadToEndAsync();但这部分不起作用。我的主要问题是如何顺序执行两个(或多个)任务。这就是我使用 ContinueWith 的原因。
  • @Thierry V:你是对的。我会告诉他你的答案。
猜你喜欢
  • 2013-02-13
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多