这样的代码,我想将大部分工作放在Task.Run中,但我不确定using语句是否仍能按预期工作。
using(MemoryStream ms = new MemoryStream())
{
Task.Run(() =>
{
/* capture ms and process the stream */
}
} // Will ms will be disposed here automatically?
感谢。
答案 0 :(得分:5)
否 - 在您的任务完成运行之前,可以运行流处理。如果可以的话,最好将使用放在任务中,或者在任务结束时手动处理处理。
LIMIT
请注意,如果您正在使用任务之外的内存流,那么您将面临处置后使用它的风险。如果可以,只使用任务中的流并将结果保存到其他地方。
var ms = new MemoryStream();
Task.Run(() =>
{
/* capture ms and process the stream */
// Dispose of the stream manually when you are done
ms.Dispose();
}
答案 1 :(得分:3)
在任务完成之前,流很可能会被关闭并处理掉。以下抛出ObjectDisposedException:
using(MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes("abc"),0,3))
{
Task.Run(() =>
{
Thread.Sleep(100);
ms.Read(new byte[3], 0, 3);
});
}
你可以将using语句移动到任务闭包中或你可以等待这样的任务:
using(MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes("abc"),0,3))
{
await Task.Run(() =>
{
Thread.Sleep(100);
var bytes = new byte[3];
ms.Read(bytes, 0, 3);
Console.WriteLine(Encoding.ASCII.GetString(bytes));
});
}
答案 2 :(得分:1)
除了上述两个变体之外,如何使用ContinueWith
进行处置?当您将任务实现作为委托传递而不是内联实现时,这特别有用:
var ms = new MemoryStream();
Task.Run(TaskUsingMemoryStream).ContinueWith(task => ms.Dispose());
您可能会争辩说,如果您在任务完成后立即处置它,那么为什么要在任务外部创建内存流,但是鉴于OP正在执行的操作,我认为在更大的范围内对此有一定的逻辑。它认为所有答案都质疑了这一选择。