【问题标题】:Dispose Stream While Still in Use by an Asynchronous Task在异步任务仍在使用时释放流
【发布时间】:2015-03-06 01:45:02
【问题描述】:

我有一个相当大的stream(代表一个图像)。我有两个任务要做:

  1. 我想使用异步方法将流上传到云端(我假设该方法由 Task.Run 支持)
  2. 在上传流时,我需要在本地读取流(以便从图像中创建缩略图)。

我的问题是:由于同一个流对象在两个不同的异步任务中被两个指针引用,我应该在哪里处理流?我可以检测引用流的指针数量吗?或者至少我可以在处理它之前检测流是否正在使用(甚至被另一个线程)?

我不知道这两个任务中哪个先完成。

【问题讨论】:

    标签: c# asp.net asynchronous stream dispose


    【解决方案1】:

    如果您的实现是线程安全的,并且您确实需要在多个地方使用一次性的,您可以使用来自 ReactiveExtensions (Rx) 的 RefCountDisposable。例如:

    RefCountDisposable refDisposable = new RefCountDisposable(stream);     
    IDisposable ref1 = refDisposable.GetDisposable();
    IDisposable ref2 = refDisposable.GetDisposable();
    

    ref1ref2 都被释放时,stream 将被释放。

    【讨论】:

      【解决方案2】:

      1) 如果它得到Task.Run 的支持,那是上传器的可怕实现。有真正的异步方法来执行 IO 调用,库应该使用它。

      2) Stream 不是线程安全的,不能有两个线程同时接触同一个流。您需要做的是打开两个流到同一个文件,同时将FileShare.Read 传递给constructor,一个用于缩略图,一个用于上传。现在,两组进程都可以在处理完自己的流后处理它们。

      【讨论】:

      • 关于 2,我没有文件,这是一种内存流(来自上传器控件)。我试图阻止复制流。
      • 然后你使用两个MemoryStreams 指向同一个byte[]This constructor 不会复制 byte[] 两个流将使用相同的数组作为它们的后备存储。
      • 抱歉不清楚。它实际上是 HttpPostedFile.InputStream (这只是一个流)
      • 然后您将需要编写(或查找)一个自定义的Stream 类,该类将流拆分并为两个较慢的读取器缓冲数据。请参阅stackoverflow.com/questions/1055872/… 了解更多信息。
      猜你喜欢
      • 2019-01-08
      • 2016-09-09
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-24
      相关资源
      最近更新 更多