在异步任务仍在使用时处置流
Dispose Stream While Still in Use by an Asynchronous Task
我有一个相当大的stream
(代表一张图片)。我有两个任务要做:
- 我想使用异步方法将流上传到云端(我假设该方法由
Task.Run
支持)
- 在上传流时,我需要在本地读取流(以便从图像创建缩略图)。
我的问题是:由于在两个不同的异步任务中,同一个流对象被两个指针引用,我应该把流放在哪里?我可以检测引用流的指针数量吗?或者至少我可以在处理它之前检测流是否正在使用(甚至被另一个线程使用)?
我不知道这两个任务中哪个先完成。
1) 如果它得到 Task.Run
的支持,那就是上传器的糟糕实现。有真正的异步方法来执行 IO 调用,库应该使用它。
2) Stream
不是线程安全的,你不能让两个线程同时接触同一个流。您需要做的是在传入 FileShare.Read
in to the constructor 时打开同一个文件的两个流,一个用于您的缩略图,一个用于您的上传。现在,两组进程都可以在完成处理后处理自己的流。
如果您的实现是线程安全的,并且您确实需要从多个地方使用一次性用品,您可以使用来自 ReactiveExtensions (Rx) 的 RefCountDisposable。例如:
RefCountDisposable refDisposable = new RefCountDisposable(stream);
IDisposable ref1 = refDisposable.GetDisposable();
IDisposable ref2 = refDisposable.GetDisposable();
当 ref1
和 ref2
都被处置时 stream
将被处置。
我有一个相当大的stream
(代表一张图片)。我有两个任务要做:
- 我想使用异步方法将流上传到云端(我假设该方法由
Task.Run
支持) - 在上传流时,我需要在本地读取流(以便从图像创建缩略图)。
我的问题是:由于在两个不同的异步任务中,同一个流对象被两个指针引用,我应该把流放在哪里?我可以检测引用流的指针数量吗?或者至少我可以在处理它之前检测流是否正在使用(甚至被另一个线程使用)?
我不知道这两个任务中哪个先完成。
1) 如果它得到 Task.Run
的支持,那就是上传器的糟糕实现。有真正的异步方法来执行 IO 调用,库应该使用它。
2) Stream
不是线程安全的,你不能让两个线程同时接触同一个流。您需要做的是在传入 FileShare.Read
in to the constructor 时打开同一个文件的两个流,一个用于您的缩略图,一个用于您的上传。现在,两组进程都可以在完成处理后处理自己的流。
如果您的实现是线程安全的,并且您确实需要从多个地方使用一次性用品,您可以使用来自 ReactiveExtensions (Rx) 的 RefCountDisposable。例如:
RefCountDisposable refDisposable = new RefCountDisposable(stream);
IDisposable ref1 = refDisposable.GetDisposable();
IDisposable ref2 = refDisposable.GetDisposable();
当 ref1
和 ref2
都被处置时 stream
将被处置。