2017-02-04 6 views
-4

비동기 메서드를 사용하고 있습니다. 타이머가 타임 아웃 이벤트를 발생시킬 때 어떻게 실행을 멈출 수 있습니까?어떻게 C#에서 비동기 메서드 실행을 막을 수 있습니까?

내 코드 :

public async Task<object> Method() 
{ 
    cts = new CancellationTokenSource(); 
    try 
    { 
     timer = new System.Timers.Timer(3000); 
     timer.Start(); 
     timer.Elapsed += (sender, e) => 
     { 
      try 
      { 
       timer_Elapsed(sender, e, cts.Token, thread); 
      } 
      catch (OperationCanceledException) 
      { 
       return; 
      } 
      catch (Exception ex) 
      { 
       return; 
      } 
     }; 
     await methodAsync(cts.Token); 
     return "message"; 
    } 
    catch (OperationCanceledException) 
    { 
     return "cancelled"; 
    } 
    catch (Exception ex) 
    { 
     return ex.Message; 
    } 
} 

// Async Call 
public async Task<object> methodAsync(CancellationToken ct) 
{ 
    try 
    { 
     pdfDocument = htmlConverter.Convert("path", ""); 
    } 
    catch(Exception ex) 
    { 
     return x.Message; 
    } 
} 

// Timer event 
void timer_Elapsed(object sender, ElapsedEventArgs e, CancellationToken ct) 
{ 
    cts.Cancel(); 
    ct.ThrowIfCancellationRequested(); 
} 
+2

'htmlConverter.Convert ("path", "")'코드를 취소하려고하는 것 같습니다. 이 코드를 취소하는 코드로 해지 토큰에 응답 할 수 있어야합니다. 그래서 유일한 대답은 당신이 취소 할 필요가있을 때 당신이 새로운 프로세스를 시작해서 죽일 필요가 있다는 것입니다. 그렇지 않으면 유일한 안전 조치로이 코드가 완료 될 수 있습니다. – Enigmativity

+0

나는 이것을 취소하려고하지 않고있다.'pdfDocument = htmlConverter.Convert ("path", "");'코드. 그냥 methodAsync() 함수를 죽이려 고하십시오. 어떨까요? –

+0

'methodAsync' 함수에서 진행되는 유일한 일은'.Convert' 호출입니다. 그래서 하나 멈추는 것은 다른 것을 멈추는 것과 같습니다. 작업/스레드를 안전하게 취소 할 수 없습니다. 취소 토큰에 응답 할 수 있어야합니다. – Enigmativity

답변

0

나는 그것을 취소 할 때 언급 시도 할 수 있다고 생각합니다. 예 :

cts.CancelAfter(TimeSpan.FromMilliseconds(5000)); 

또한 호출 된 메소드에서 취소 토큰을 사용해야합니다. 언제 취소해야하는지 알 수 있습니다. 작업을 취소하는 것은 어떻게 작동하는지

1

은 다음과 같습니다

public async Task<object> Method() 
{ 
    cts = new CancellationTokenSource(); 
    await methodAsync(cts.Token); 
    return "message"; 
} 

public Task<object> methodAsync(CancellationToken ct) 
{ 
    for (var i = 0; i < 1000000; i++) 
    { 
     if (ct.IsCancellationRequested) 
     { 
      break; 
     } 
     //Do a small part of the overall task based on `i` 
    } 
    return result; 
} 

당신은 작업을 취소 할 때 알 수 ct.IsCancellationRequested의 특성의 변화에 ​​대응해야한다. 한 스레드/작업이 다른 스레드/작업을 취소하는 안전한 방법은 없습니다.

귀하의 경우에는 CancellationToken에 대해 알지 못하는 하나의 메소드를 호출하려고하므로이 작업을 안전하게 취소 할 수 없습니다. 스레드/작업이 계속 완료되도록해야합니다.