2016-03-23 3 views
9

Это моя ситуация:Правильное использование 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(); 
    } 

задача не будет отменена, при вызове метода cancelToken. Как так?

Я прочитал Microsoft guide, а также другие вопросы, связанные с отменой задачи.

Но все еще с трудом их правильно использовать.

+0

В вашем цикле, вы вызывать другой метод асинхронного или выполнения вашей длительной работы? –

+0

Просьба предоставить более полный образец кода того, что вы делаете - то есть, что вызывает ReceiveMessagesFromDeviceAsync? Какой экземпляр CancellationToken передается в этот метод? – auburg

+0

Я сделал редактирование. – BlueCastle

ответ

6

Вы можете рассмотреть CancellationToken как флаг, указав, получен ли сигнал отмены. Таким образом:

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(); 
} 

Если вы хотите LongRunningTask быть отменены, вы должны использовать CancellationToken внутри тела задачи и проверить его, когда это необходимо, например:

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

Не могли бы вы объяснить это на примере? – BlueCastle

+0

@BlueCastle См. Редактирование. –

+0

Если в конструкторе вызывается cancelationTokenSource.Cancel(), задача отменяется. Но Задача не отменяется при вызове метода cancelTokenSource.Cancel() из метода cancelToken. – BlueCastle

Смежные вопросы