【问题标题】:Force any task to be attached to parent强制将任何任务附加到父级
【发布时间】:2015-11-01 14:13:24
【问题描述】:

我正在尝试创建一个扩展方法,它将任何任务附加到父级。

扩展代码:

internal static class TaskHelpers
{
    public static Task AttachToParrent(this Task task)
    {
        var tsc = new TaskCompletionSource<Task>(task.CreationOptions &    TaskCreationOptions.AttachedToParent);

        task.ContinueWith(_ => tsc.TrySetResult(task), TaskContinuationOptions.OnlyOnRanToCompletion);

        task.ContinueWith(t => tsc.TrySetException(task.Exception ?? new AggregateException(new ApplicationException("Unknown"))), TaskContinuationOptions.OnlyOnFaulted);

        task.ContinueWith(t => tsc.TrySetCanceled(), TaskContinuationOptions.OnlyOnCanceled);

        return tsc.Task.Unwrap();
    }
}

测试代码:

  static void Main(string[] args)
    {
        var  cancellationTokenSource = new CancellationTokenSource();

        var task1 = Task.Factory.StartNew(() =>
        {
            var task2 = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 5; i++)
                {


                    if (!cancellationTokenSource.IsCancellationRequested)
                    {
                        Console.WriteLine(i);

                        Thread.Sleep(5000);
                    }
                    else
                    {
                        Console.WriteLine("Loop cancelled.");

                        break;
                    }
                }

            }, cancellationTokenSource.Token).AttachToParrent();

            var task3 = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 5; i++)
                {

                    if (!cancellationTokenSource.IsCancellationRequested)
                    {
                        Console.WriteLine(i*10);

                        Thread.Sleep(5000);
                    }
                    else
                    {
                        Console.WriteLine("Loop cancelled.");

                        break;
                    }
                }

            }, cancellationTokenSource.Token).AttachToParrent();
        }, cancellationTokenSource.Token);

        Console.WriteLine("Enter to cancel");

        Console.ReadKey();

        cancellationTokenSource.Cancel();

        Console.WriteLine("Waiting To Be Cancelled");

        task1.Wait();

        Console.WriteLine("Task Cancelled");

        Console.ReadKey();
    }

父任务立即取消,无需等待内部任务完成。我该如何解决它,作为输入,我得到了我在父调度程序任务中执行的任务。我想执行附加到父级的任何任务。

【问题讨论】:

    标签: c# task-parallel-library task unwrap taskcompletionsource


    【解决方案1】:

    调用Task.Factory.StartNew时只需提供TaskCreationOptions.AttachedToParent(仅在创建子任务时):

    var task2 = Task.Factory.StartNew(..., cancellationTokenSource.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Current);
    

    有关附加/分离任务的更多信息:请参阅MSDN

    【讨论】:

    • 我不是创建任务的人的问题。
    【解决方案2】:

    发现问题出在

    var tsc = new TaskCompletionSource<Task>(task.CreationOptions &    TaskCreationOptions.AttachedToParent); 
    

    tsc,CreationOptions 保持为 nooptions。

    改为

    var tsc = new TaskCompletionSource<Task>(TaskCreationOptions.AttachedToParent); 
    

    现在一切正常。

    【讨论】:

    • 也许您打算使用|(按位或)?按位与 (&amp;) 是逻辑与。在英语中,当您说“and”时,有时您的意思是“additionally”,而在逻辑中(或者,至少在这里),它总是表示“intersection/overlap”。
    猜你喜欢
    • 1970-01-01
    • 2013-10-24
    • 2020-02-19
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多