2010-09-07 1 views
17

Я пытаюсь программно связать асинхронные операции в C# 4, такие как Writes для данного объекта Stream. Я изначально делал это «вручную», перехватывая обратные вызовы от одной операции до следующей, но я думал, что попробую параллельную библиотеку задач .NET 4, чтобы избавить себя от необходимости повторного создания параллельного колеса.Как связать асинхронные операции с библиотекой параллельных задач в .NET 4?

Для начала, я обернуть мои звонки в асинхронных задачах следующим образом:

public static Task CreateWriteTask(Stream stream, byte[] data) 
{ 
    return Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, data, 0, data.Length, null); 
} 

Продолжение сделало цепочки синхронных операций очень легко (если вы простите название неудачного метода):

public static Task ChainFlush(Stream stream, Task precedingTask) 
{ 
    return precedingTask.ContinueWith(x => stream.Flush()); 
} 

Но нет версии метода Task.ContinueWith, который принимает операцию async так же, как TaskFactory.FromAsync.

Таким образом, если предположить, что я упорно с помощью TPL, что я искал правильное применение этого метода:

public static Task ChainWrite(Stream stream, byte[] data, Task precedingTask) 
{ 
    //? 
} 
+0

TaskCreationOptions.AttachedToParent? –

ответ

12

Моя лучшая идея до сих пор является в цепочке создания новой задачи записи , а затем использовать метод расширения разворачивать, чтобы превратить Task<Task> обратно в Task:

public static Task ChainWrite(Stream stream, byte[] data, Task precedingTask) 
{ 
    return precedingTask.ContinueWith(x => CreateWriteTask(stream, data)).Unwrap(); 
} 
1

Попробуйте ContinueWhenAll() или ContinueWhenAny() вместо ContinueWith(). См. here.

+0

Вот ссылка MSDN: - http://msdn.microsoft.com/en-us/library/dd997423.aspx – prashanth

+1

Интересные ссылки, но на самом деле не решают мою проблему. ContinueWhenAll/Any не имеют перегрузок для приема Async Ops, просто Action и Func . Реализация Iterator в вашей ссылке - интересная идея, и я могу адаптировать ее к другой проблеме, с которой я столкнулся, но она предполагает, что я делаю то же самое снова и снова, и в основном является итеративным способом делать то, что я ', упомянутый в моем существующем ответе (создание задачи в другой задаче). Спасибо, в любом случае! – FacticiusVir

3

Насколько я понимаю, это является неудачным последствием неконтролируемого запуска задачи. Поскольку вы никогда не знаете, когда задача запускается, не может быть перегрузка, как

precedingTask.ContinueWith(Task nextTask) 

потому, что когда-то создал, он уже может быть запущен, когда вы получаете «ContinueWith». Кроме того, это также создавало бы беспорядок типов. Какой должен быть вид здесь:

precedingTask<T>.ContinueWith(Task<..what?..> nextTask) 

предшествующий возвращает T, поэтому следующее берет то, что и что возвращает? Однако это можно решить с помощью закрытий.

 Смежные вопросы

  • Нет связанных вопросов^_^