2014-09-24 4 views
4

Я видел, что в .NET 4.5, что Task.Run() является эквивалентомTaskCreationOptions.DenyChildAttach в .NET 4

Task.Factory.StartNew(someAction, 
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); 

Но в .NET 4.0, TaskCreationOptions.DenyChildAttach не существует. Это где TaskEx.Run входит? Комментарий в this question, по-видимому, указывает на то, что, но не уточняется. Что эквивалентно в .NET 4.0 для .NET 4.5 Task.Run?

+0

Я не вижу, что 4,5 '' Factory.StartNew' использует DenyChildAttach' (см. http://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/TaskFactory.cs) По умолчанию 'TaskFactory', используемый с' Task.Factory', создается по умолчанию 'TaskCreationOptions.None' (http: // sourcesource.microsoft.com/#mscorlib/system/threading/Tasks/TaskFactory.cs) Где вы узнали об этом? –

+0

MSDN заявляет, что Task.Run в .NET 4.5 эквивалентен использованию DenyChildAttach: http://msdn.microsoft.com/en-us/library/hh195051.aspx aslo http://blogs.msdn.com/b/ pfxteam/archive/2011/10/24/10229468.aspx –

+0

Извините, я прочитал это назад. по какой-то причине я прочитал, что 'Task.Factory.StartNew' по умолчанию' DenyChildAttach'. Да, 'Task.Run()' по умолчанию соответствует этому, а не 'Task.Factory.StartNew (Action)'. В разрядных битах нет класса TaskEx. Эквивалент в 4.0 - это * не * использование 'TaskCreationOptions.AttachedToParent'. Задача не является дочерней без 'AttachedToParent' –

ответ

6

Опция DenyChildAttach не только не существует в перечислении TaskCreationOptions, ее нет в самой структуре. Код, который на самом деле отрицает попытку вложения дочерней задачи не существует в .Net 4.0. (больше в New TaskCreationOptions and TaskContinuationOptions in .NET 4.5).

Таким образом, точный эквивалент Task.Run не существует и не может существовать в .Net 4.0. Ближе всего к нему было бы просто не использовать значение AttachedToParent в этом перечислении:

public static Task<TResult> Run<TResult>(Func<TResult> function) 
{ 
    return Task.Factory.StartNew(
     function, 
     CancellationToken.None, 
     TaskCreationOptions.None, 
     TaskScheduler.Default); 
} 

Более важным отличием ИМО является поддержка async делегатов в Task.Run. Если вы передадите делегата async (т. Е. Func<Task<TResult>>) на номер Factory.StartNew, вы вернетесь в обратном направлении Task<Task<TResult>> вместо Task<TResult>, поскольку некоторые ожидали бы, что является source of many headaches. Решение, что является использование метода TaskExtensions.Unwrap расширения, «Создает прокси Task, который представляет асинхронную операцию в Task<Task<T>>»:

public static Task<TResult> Run<TResult>(Func<Task<TResult>> function) 
{ 
    return Task.Factory.StartNew(
     function, 
     CancellationToken.None, 
     TaskCreationOptions.None, 
     TaskScheduler.Default).Unwrap(); 
}