几项任务取消

时间:2014-03-24 12:55:56

标签: c# .net c#-4.0 task multitasking

有一项顶级任务可以启动另一项任务。

var token = _cancellationTokenSource.Token;
_task = new Task(() => WorkAction(this, token), token); //Top level task

内部任务实现是:

public string FindDevice(IProgressViewModel progressViewModel, 
                         CancellationToken cancellationToken) {

        for (int i = 0; i < orderedComPortsList.Count; i++) {
            try {
                cancellationToken.ThrowIfCancellationRequested();
            } catch (OperationCanceledException) {
                return null;
            }
            string curPort = orderedComPortsList[i];
            if (InnerIsDeviceOnline(deviceModelId, curPort)) //The real long work
                return curPort;
            progressViewModel.CurrentValue = i;
        }
        return null;
    }

通过此实现,仅当最后一个InnerIsDeviceOnline结束时才会取消。如何实现FindDevice使其立即取消?

更新1。

我们可以这样做:

 bool? result = null;
            Task<bool> parent = new Task<bool>(() => {
                bool? res = result;
                Task.Factory.StartNew(() => {
                    while (res==null) {                           
                        cancellationToken.ThrowIfCancellationRequested();
                        Thread.Sleep(50);
                    }
                }, TaskCreationOptions.AttachedToParent);

                result = InnerIsDeviceOnline(deviceModelId, comPort);
                return result.Value;
            }, cancellationToken);

            return parent;

问题在于它永远不会完成(我不知道为什么)。但这会立即取消。

1 个答案:

答案 0 :(得分:1)

为了优雅地取消长时间运行的操作,您的整个API需要以您需要的特定粒度支持取消。如果长时间运行的API不支持CancellationToken,则您需要提供一个接口层来提供该支持。例如,异步WebRequest.BeginGetResponse不支持CancellationToken,但我能够通过此扩展方法支持它,该方法调用Abort()以响应CancellationToken被取消:

https://github.com/openstacknetsdk/openstack.net/blob/master/src/corelib/Core/WebRequestExtensions.cs