簡體   English   中英

正確使用CancellationToken

[英]Correct use of 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指南 ,其他Stackoverflow有關任務取消的問題。

但仍然難以正確使用它們。

您可以將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();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM