2016-11-15 3 views
5

Код вроде этого, я хочу поместить большую часть работы в Task.Run, но я не уверен, что оператор using по-прежнему будет работать, как ожидалось.Можно ли вызвать Task.Run внутри инструкции using?

using(MemoryStream ms = new MemoryStream()) 
{ 
    Task.Run(() => 
    { 
     /* capture ms and process the stream */ 
    } 
} // Will ms will be disposed here automatically? 

Спасибо.

+0

Реальный вопрос «я могу игнорировать' await' внутри инструкции 'using'? Это действительно не имеет никакого отношения к 'Task.Run'. –

ответ

5

Нет - Реализация потока может выполняться до завершения вашей задачи. Вам было бы лучше помещать использование внутри задачи, если можно, или вручную обрабатывать удаление в конце Задачи.

var ms = new MemoryStream(); 
Task.Run(() => 
{ 
    /* capture ms and process the stream */ 

    // Dispose of the stream manually when you are done 
    ms.Dispose(); 
} 

Обратите внимание, что если вы используете поток памяти за пределами задачи, то вы рискуете использовать его после того, как он расположен. Если вы можете, используйте поток только внутри задачи и сохраняйте результаты в другом месте.

Task.Run(() => 
{ 
    using(var ms = new MemoryStream()) 
    { 
     /* capture ms and process the stream */ 
    } 
} 
+0

Спасибо, я думаю, если я стану «ждать» впереди Task.Run, это заставит все работать, правильно? – codewarrior

+0

Yep - @Letseatlunch имеет пример этого также –

+0

Не имеет значения, если dispose вызывается дважды – Mick

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(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)); 
    }); 
} 
Смежные вопросы