長時間実行しているWCFの関数があるので、backgroundworkerでUI内の関数を呼び出して...この場合、サービスの実行を停止する方法はありますか?
3 に答える
Async 呼び出しを使用している場合に理解しておくべき重要な点の 1 つは、要求をキャンセルして、開始されたサービスからの応答を防ぐ方法がまだないことです。競合状態を回避するために応答を処理する際にインテリジェントになるのは、UI 次第です。幸いなことに、これを行う簡単な方法があります。
この例は、注文を検索するためのものです - UI によって駆動されます。結果が返されるまでに数秒かかる場合があり、ユーザーが 2 つの検索を連続して実行しているとします。
したがって、ユーザーが 2 つの検索を実行し、最初の検索が 2 番目の検索の後に返される場合、最初の検索の結果を表示しないようにする必要があります。
private int _searchRequestID = 0; // need one for each WCF method you call
// Call our service...
// The call is made using the overload to the Async method with 'UserToken'.
// When the call completes we check the ID matches to avoid a nasty
// race condition
_searchRequestID = _searchRequestID++;
client.SearchOrdersCompleted += (s, e) =>
{
if (_searchRequestID != (int)e.UserState))
{
return; // avoid nasty race condition
}
// ok to handle response ...
}
client.SearchOrdersAsync(searchMessage, _searchRequestID);
BackgroundWorker は必要ないかもしれません。IsOneWay 操作を行うか、非同期パターンを実装することができます。スレッド化の問題を回避するには、SynchronizationContextの使用を検討してください。 WCF サービスのプログラミングは、これらを説明するのに非常に役立ちます。
サービスに静的な ManualResetEvent を設定する CancelOperation() メソッドを作成します。Operation メソッドでこのイベントを頻繁に確認してください。または、サービスが複数の操作呼び出しを同時に処理できる場合は、CancelOperation(Guid operationId) にすることもできます。