【问题标题】:How to correctly handle a disposable Task result?如何正确处理一次性任务结果?
【发布时间】:2014-06-22 06:04:32
【问题描述】:

我有一个场景,其中 Task1 初始化并返回一个 IDisposable 对象以在这样的链式 Task2 中使用:

Task.Factory.StartNew<Stream>(() =>
{
    // open and write stream
})
.ContinueWith(prevTask => 
{
    var stream = prevTask.Result;  // possible AggregateException
    // read stream and close it
});

问题是:如何正确处置对象?一个有趣的情况可能是这样的:Task1 打开+读取流,然后发生异常,该异常在 Task2 中重新抛出,因此 Task2 将看不到仍然打开的原始流。

有没有像using () { ... } 这样众所周知的模式来做到这一点?

【问题讨论】:

  • 不能用 await 关键字吗?
  • 不,它是 .NET4 代码
  • @metalheart:您仍然可以在 .NET 4 中使用 async/await,使用 Microsoft.Bcl.Async 包。不过,您确实需要 C# 5 编译器(VS2012 或更高版本)。
  • "Task1 打开 + 读取流,然后发生异常" - 任务 1 需要注意适当地处理流,直到它完全完成使用它并且不再抛出任何异常.只有在这一点上应该例如设置一个标志,让它知道不再处理它。
  • 你真的需要两个独立的Tasks吗?不能把所有代码都放在StartNew() lambda 里面吗?

标签: .net task-parallel-library


【解决方案1】:

如 cmets 中所述,您正在寻找的模式是使用await 关键字调用的。 重新抛出异常的原因是您正在访问prevTask.Result。如果您首先调用prevTask.IsFaulted,那么您将能够做出反应,而不会重新引发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2020-05-29
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    相关资源
    最近更新 更多