17

特定のStreamオブジェクトへの書き込みなど、C#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ただし、と同じ方法で非同期操作を受け入れるバージョンのメソッドはありませんTaskFactory.FromAsync

したがって、TPLを使い続けると仮定すると、このメソッドの正しい実装を探しています。

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

3 に答える 3

12

これまでの私の最善のアイデアは、新しい書き込みタスクの作成を連鎖させてから、Unwrap拡張メソッドを使用して次のようにTask<Task>戻すことTaskです。

public static Task ChainWrite(Stream stream, byte[] data, Task precedingTask)
{
    return precedingTask.ContinueWith(x => CreateWriteTask(stream, data)).Unwrap();
}
于 2010-09-07T16:49:30.283 に答える
3

私が理解している限りでは、これはタスクがいつ開始されるかを制御できないことによる不幸な結果です。タスクがいつ開始されるかわからないため、次のようなオーバーロードはあり得ません。

precedingTask.ContinueWith(Task nextTask)

一度作成されると、「ContinueWith」に到達したときにすでに開始されている可能性があるためです。その上、それはまた型の混乱を引き起こします。ここでのタイプは次のとおりです。

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

前は T を返すので、次は何を受け取って何を返しますか? :) ただし、これはクロージャーで解決できます。

于 2010-10-16T07:51:42.260 に答える
1

の代わりにContinueWhenAll()または を試してください。ここを参照してください。ContinueWhenAny()ContinueWith()

于 2010-09-07T21:54:21.493 に答える