2

ツリーがあり、ユーザーが任意のノードをクリックすると、Web サービスからデータを照会し、結果を置き換えます。ただし、時間がかかる場合もあります。そこで、Web サービス呼び出しをタスクにラップしようとしました。タスクが完了していないときにタスクをキャンセルし、ユーザーが他のノードをクリックしたいと思います。以下は私のサンプルコードです。ただし、_cancelTokenSource.Cancel() が実行されても、キャンセル タスク ブロックは実行できません。MSDN が提供するサンプルのほとんどは、I/O バウンドではなく、CPU バウンドに基づいています。Webサービスをすべてキャンセルする方法を誰か教えてもらえますか? 前もって感謝します

private void OnNodeClicked(int id)
{
 if (_cancelTokenSource != null)
     _cancelTokenSource.Cancel();

 IsRunning = true;
 var uiSchedule = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();
 _cancelTokenSource = new CancellationTokenSource();
 var loadDataTask = System.Threading.Tasks.Task.Factory.StartNew<int[]>(() =>
 {
     // Call web service here
 }, _cancelTokenSource.Token);

 loadDataTask.ContinueWith((result) =>
 {
     // Populate data
     IsRunning = false;
 }, CancellationToken.None, System.Threading.Tasks.TaskContinuationOptions.OnlyOnRanToCompletion, uiSchedule);

 loadDataTask.ContinueWith((result) =>
 {
     // set cancel state here
     IsRunning = false;
 }, CancellationToken.None, System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled, uiSchedule);

}

4

1 に答える 1

0

CancellationTokenSourceおよびそのトークンは、あるスレッド (またはタスク) が別のスレッドがタスクのキャンセルを要求しているかどうかを照会する方法です。もちろん、これには、そのトークンをチェックするコードを作成する必要があります (したがって、少なくとも 1 回、通常は定期的に実行されます)。タスクまたはキャンセル トークンについて何も知らない、生成されたコード (Web サービス プロキシ) に委任した場合、それは使用できません。

Begin メソッドを使用して呼び出しを開始した場合は、 を使用WebClientAsyncResult.Abort()して呼び出しを中止できます。例えば:

IAsyncResult ar = obj.BeginFunCall(5,5,null,null);
//...
if (!ar.IsCompleted) //if the request is not completed  { 
  WebClientAsyncResult wcar = (WebClientAsyncResult)ar;
  wcar.Abort();//abort the call to web service 
}
于 2012-08-13T14:22:30.093 に答える