2016-03-23 12 views
9

Dies ist meine Situation:Korrekte Verwendung von CancellationToken

private CancellationTokenSource cancellationTokenSource; 
    private CancellationToken cancellationToken; 

    public IoTHub() 
    { 
     cancellationTokenSource = new CancellationTokenSource(); 
     cancellationToken = cancellationTokenSource.Token; 

     receive(); 
    } 

    private void receive() 
    { 
     eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, iotHubD2cEndpoint); 
     var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds; 

     foreach (string partition in d2cPartitions) 
     { 
      ReceiveMessagesFromDeviceAsync(partition, cancellationToken); 
     } 
    } 

    private async Task ReceiveMessagesFromDeviceAsync(CancellationToken ct) 
    { 
     var eventHubReceiver = eventHubClient.GetDefaultConsumerGroup().CreateReceiver(partition, DateTime.UtcNow); 

     while (true) 
     { 
      if(ct.IsCancellationRequested) 
      { 
       break; 
      } 

      EventData eventData = await eventHubReceiver.ReceiveAsync(); 
      if (eventData == null) continue; 

      string data = Encoding.UTF8.GetString(eventData.GetBytes()); 

      // Javascript function with Websocket 
      Clients.All.setMessage(data); 
     } 
    } 

    public void cancelToken() 
    { 
     cancellationTokenSource.Cancel(); 
    } 

Die Aufgabe wird nicht abgebrochen, wenn die cancelToken Methode aufrufen. Woher?

Ich habe die Microsoft guide gelesen, eine andere Stackoverflow Fragen über Aufgaben Stornierung.

Aber immer noch Schwierigkeiten haben, sie richtig zu verwenden.

+0

In der Schleife, rufen Sie eine andere Asynchron-Methode oder Ihre lang andauernde Operation durchführen? –

+0

Bitte geben Sie ein vollständigeres Codebeispiel von dem, was Sie tun - d. H. Was ruft ReceiveMessagesFromDeviceAsync auf? Welche CancellationToken-Instanz wird in diese Methode übergeben? – auburg

+0

Ich habe den Schnitt gemacht. – BlueCastle

Antwort

6

Sie können CancellationToken wie ein Flag betrachten, das anzeigt, ob ein Löschsignal empfangen wird. Also:

while (true) 
{ 
    //you check the "flag" here, to see if the operation is cancelled, correct usage 
    if(ct.IsCancellationRequested) 
    { 
     break; 
    } 

    //your instance of CancellationToken (ct) can't stop this task from running 
    await LongRunningTask(); 
} 

Wenn Sie LongRunningTask abgesagt werden, sollten Sie CancellationToken innerhalb der Task Körper verwenden und es überprüfen, wenn nötig, wie folgt aus:

async Task LongRunningTask() 
{ 
    await DoPrepareWorkAsync(); 

    if (ct.IsCancellationRequested) 
    { 
     //it's cancelled! 
     return; 
    } 

    //let's do it 
    await DoItAsync(); 

    if (ct.IsCancellationRequested) 
    { 
     //oh, it's cancelled after we already did something! 
     //fortunately we have rollback function 
     await RollbackAsync(); 
    } 
} 
+0

Können Sie das mit einem Beispiel erklären? – BlueCastle

+0

@BlueCastle Siehe die Änderung. –

+0

Wenn im Konstruktor cancellationTokenSource.Cancel() aufgerufen wird, wird die Task abgebrochen. Die Task wird jedoch nicht abgebrochen, wenn cancelTokenSource.Cancel() von der cancelToken-Methode aufgerufen wird. – BlueCastle