10

方法があります

public Task<Task> DoSomeWorkOnARemoteMachine()

非常に説明的に言えば、次の方法でリモートマシンでいくつかの作業を実行します。

  1. 作業を行う必要があることを知らせるメッセージ バス上のメッセージをキューに入れる
  2. リモート エージェントがメッセージを受け取り、作業を実行します。
  3. 作業が終了し、エージェントはメッセージ バスでメッセージをキューに入れ、作業が完了したことを伝えます。
  4. 作業を呼び出したアプリケーションは、作業が完了したというメッセージを受け取ります

私が使用した理由Task<Task>は、1 つ目Task<>はメッセージのキューイングのためです。Task一方、リモート マシンで作業が完了したとき (つまり、エージェントからのメッセージが受信されたとき) は、内部が完了します。作業の実行中にリモート エージェントがキャッチした例外は、完了メッセージと共に渡され、内部のTask完了時に再度スローされます。

このメソッドを呼び出すには、次を使用します。

await await DoSomeWorkOnARemoteMachine();

メッセージがキューに入れられてジョブを実行し、ジョブを完了して例外を受け取るまで待機します。ただし、ジョブがリモート エージェントで完了したかどうかに関心がない場合は、次のように呼びます。

await DoSomeWorkOnARemoteMachine();

これはawaitインナーではありませんTask。ただし、内部Task(リモート エージェントからメッセージを受信し、例外を再スローする) は、まだある時点で実行されます。これはちょっともったいない気がするので、結果が出ないときは実行するのは避けたいと思いawaitます。

したがって、私の質問は次のとおりです。それTaskがedされているかどうかを「認識」しawait、そうでない場合は実行しないか、他のコードパス(空のTask本体など)を実行することは可能ですか。

「発射して忘れる」フラグを渡す、または「発射して忘れる」のオーバーロードを追加するなど、実装できる代替手段があることを認識しています。クライアントAPIを変更せずにこれを実装できれば素晴らしいのですが

この種のリモート作業の実行を実装する他のプロジェクトに関する回答も素晴らしいでしょう!

4

3 に答える 3

3

簡単または効率的に達成できるとは思いません (Task.GetAwaiter で遊ぶのは悪い考えであり、関数内からアクセスすることはできません。Noseratio の回答を参照してください)。代替ソリューションは次のとおりです。

Taskソリューション n°1 :実行用の関数パラメーター

await DoSomeWorkOnARemoteMachine(false) //Indicates that DoSomeWork shouldn't be executed

ソリューション n°2 : 明示的なタスクの実行

Task t = await DoSomeWorkOnARemoteMachine() ;
t.Start(); // For example, if you want to execute the resulting Task. 
           // You can also dispatch it to an other thread, etc...
于 2013-11-06T08:28:53.843 に答える
3

これは非常に興味深い質問です。それでも、私がそれを正しく理解していれば、あなたが提示した方法では、これは意味をなさないので不可能だと思います(IMO)。次のモデルを見てみましょう (間違っていたら教えてください):

static async Task<Task> DoSomeWorkOnARemoteMachine()
{
    // Point X: 
    await Task.Delay(1000);
    // Point Y: 
    Console.WriteLine("request sent");
    var taskInner = Task.Delay(2000);
    // Point A: here you want to know if there's an await at Point B
    return taskInner;
}

static async Task Test()
{
    var taskOuter = DoWorkAsync();
    // Point Z: 
    await taskOuter;
    // Point B: 
    await taskOuter.Result; // await taskInner
    Console.WriteLine("request received");
}

ポイント Aawaitで、ポイントBに があるかどうかを知りたいとします。しかし現時点では、ポイント Bはまだ未来にあり、まだ発生していません。そのためにはタイムマシンが必要です:)

[UPDATE]同様に、ポイント Xでは、コード フローがまだZawaitに到達していないため、ポイント Zについて知ることはできません。

ただし、Yの場合、理論的にはZのことを知ることができます(まだBについてはわかりません)。ただし、そのような情報を入手することが技術的に可能かどうかはわかりません。await

于 2013-11-06T08:23:41.887 に答える