次のシナリオがあります。
Webサービスの開始を要求しているクライアント
public bool Start(MyProject project, string error)
メソッドでクライアントからの呼び出しを受信するWebサービス
public event EventHandler<StartEventArgs> startEvent;
public bool Start(MyProject project, string error)
{
Task<bool> result = StartAsync(project, error);
return result.Result;
}
protected virtual void OnStart(StartEventArgs e)
{
// thread safe trick, snapshot of event
var se = startEvent;
if (se != null)
{
startEvent(this, e);
}
}
private Task<bool> StartAsync(MyProject project, string error)
{
var taskCompletion = new TaskCompletionSource<bool>();
this.startEvent += (p, e) => taskCompletion.TrySetResult((e.Error == string.Empty) ? true : false);
this.OnStart(new StartEventArgs(project, error));
return taskCompletion.Task;
}
Webサービスにあるイベントをサブスクライブしているアプリケーション:
app.Start += EventHandler(App_Start)
private bool App_Start()
{
// does something
returns true/false
}
Webサービスでタスクのイベントを発生させ、app.exeの関数が終了するのを待ってから、ここに戻ってタスクが正常に完了したことをユーザーに通知します。
これを行う方法はわかりませんが、理論的には次のようになります。
Task<bool> startTask = Task.Factory.StartNew(() => { OnStart() });
startTask.WaitAll(); // I think this is what I would need to for 4.0
return startTask.Result
私がやろうとしていることを誰かが見ることができるように、私が十分に説明的であることを願っています。サービスがクライアントについて何も知る必要がなく、タスクを実行するだけで、イベントの実行が終了したら、このポイントに戻って、成功/失敗を表すブール値をクライアントに返す必要があります。
これは可能ですか、それとも私はこれで本当に間違ったアプローチを取っていますか?
更新:明らかにOnStartはイベントではないので、あなたが私に説明しようとしていることをどのように行うのですか?
イベントベースの非同期パターンを説明するイベントをTask<T>
viaにラップできTaskCompletionSource<T>
ます。基本的なパターンは通常、次のようなものです。
Task<bool> StartAsync()
{
var tcs = new TaskCompletionSource<bool>();
// When the event returns, set the result, which "completes" the task
service.OnStarted += (o,e) => tcs.TrySetResult(e.Success);
// If an error occurs, error out the task (optional)
service.OnStartError += (o,e) => tcs.TrySetException(e.Exception);
// Start the service call
service.Start();
// Return the Task<T>
return tcs.Task;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加