2017-07-11 4 views
-1

長時間の作業呼び出しDoLongWork()を持つサードパーティ製のいくつかのクラスを使用しています。 ユーザーが "DoLongWork"を停止したい場合、StopWork()メソッドを呼び出す必要があります。 DoLongWorkメソッドが動作しているとき、UIにロードバーの一部が表示される必要があります。サードパーティ製の長時間実行メソッドをwrapするタスクの取り消しを処理する方法

サードパーティのプロキシクラスを作成したいと思います。 このクラスでは、私はのstartWorkというメソッドを作成します - このメソッドは、タスクを返し、ユーザーがCancellationToken 2つのアクションを使用してタスクをキャンセルされ作られます

1)サードパーティの方法「StopWorkは」

と呼ばれます

2)UIがローディングバーを停止します。

私はこれを試していますが、サードパーティのプロキシクラスの取り消しをキャッチし、キャンセルをViewModelクラスにバブリングする際にいくつかの問題があります。

public class MyViewModel 
{ 
    private CancellationTokenSource _cancellationTokenSource; 
    private ThirdPartyServiceProxy _thirdPartyServiceProxy = new ThirdPartyServiceProxy(); 
    public bool IsUIInLoadingMode { get; set; } 
    public async void Start() 
    { 
     try 
     { 
      _cancellationTokenSource = new CancellationTokenSource(); 
      IsUIInLoadingMode = true; 
      await _thirdPartyServiceProxy.StartWork(_cancellationTokenSource.Token); 
      _cancellationTokenSource = null; 
     } 
     catch (OperationCanceledException)/*Issue - This never called*/ 
     { 
      IsUIInLoadingMode = false; 
     } 
    } 
    public void Stop() 
    { 
     _cancellationTokenSource?.Cancel(); 
    } 
} 

public class ThirdPartyServiceProxy 
{ 
    private ThirdPartyService _thirdPartyService = new ThirdPartyService(); 
    public Task StartWork(CancellationToken token) 
    { 
     var task = Task.Factory.StartNew(() => 
     { 
      _thirdPartyService.DoLongWork(); 
     },token); 

     //?? - Handle when task canceld - call _thirdPartyService.StopWork(); 

     return task; 
    } 
} 
+1

'_thirdPartyService.DoLongWork();'はCancellationTokenを受け入れていないので、これはうまくいかないでしょう。 'Task.Factory.StartNew'に渡されたトークンは、タスクが実際に実行される前にCancelが呼び出されたときにのみ有効です。 –

答えて

2

couple of common ways to observe cancellation tokensあります:ThrowIfCancellationRequestedRegisterでコールバックを登録して定期的なポーリングが。

DoLongWorkでコードを制御していないため、この場合、ポーリングはできません。コールバックを登録する必要があります。これはより多くの作業です。

public void DoWork(CancellationToken token) 
{ 
    token.ThrowIfCancellationRequested(); 
    using (token.Register(() => _thirdPartyService.StopWork())) 
    _thirdPartyService.DoLongWork(); 
} 

このラッパーはStopWorkでキャンセルした場合DoLongWorkOperationCanceledExceptionをスローすることを前提としています。

ラッパーはその後として呼び出すことができます:私はTask.Runに切り替えている側の注意点として、

await Task.Run(() => _thirdPartyServiceProxy.StartWork(_cancellationTokenSource.Token)); 

。これは、StartNew is dangerousです。

関連する問題