我正在查看codeplex上的下载管理器类型项目并且遇到了这个: http://nthdownload.codeplex.com/
浏览我在AddDownloads
等方法中运行的代码,如下所示:
AddDownloads
启动_downloadQueue.AddDownloads任务并继续执行viewMaintenanceTask
任务。如果你看看在这两个任务和下游发生的方法和事情,似乎一切都是同步的。
另请阅读此博客文章,Synchronous tasks with Task我正在尝试了解在TaskCompletionSource
中包装同步方法的优势(如果有的话)。是因为它为API使用者提供了在单独的线程上启动任务的选项,或者只是因为您希望将该方法用作Task
。包含在TaskCompletionSource
中的同步方法是否受益于并行处理?
private Task<QueueOperation> AddDownloads(IEnumerable<IDownload> downloads, out Task<QueueOperation> startTask)
{
var addTask = _downloadQueue.AddDownloads(downloads, out startTask);
// Maintain views
var viewMaintenanceTask = addTask.ContinueWith(t =>
{
if (t.Exception == null)
{
var addedDownloads = t.Result.DownloadErrors.Where(k => k.Value == null).Select(k => k.Key).ToList();
var activeDownloads = ActiveDownloads.ToList();
AddToActiveDownloads(addedDownloads.Except(activeDownloads).ToList(), false);
}
else
{
// Rethrow exception, this ensures it'll bubble up to any further ContinueWith chained off this task
throw t.Exception;
}
return t.Result;
});
return viewMaintenanceTask;
}
博客文章中的示例方法,将同步操作包装在TaskCompletionSource
:
var tcs = new TaskCompletionSource<object>();
try
{
object result = model.Deserialize(stream, null, type);
tcs.SetResult(result);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
return tcs.Task;
答案 0 :(得分:9)
包装在TaskCompletionSource中的同步方法是否受益于并行处理?
没有。创建TaskCompletionSource
使不以任何方式,形状或形式创建新线程。
你在底部给出的代码是毫无意义的 - 当方法返回时,任务已经完成(或出现故障)。如果您必须使用任务,那么仅才有用。我可能会把它改成:
try
{
return Task.FromResult(model.Deserialize(stream, null, type));
}
catch (Exception ex)
{
// There's no Task.FromException, unfortunately.
var tcs = new TaskCompletionSource<object>();
tcs.SetException(ex);
return tcs.Task;
}
在C#中,它相当于在没有async
表达式的情况下编写await
方法:
public static async Task<object> Deserialize(Model model, Stream stream,
Type type)
{
return model.Deserialize(stream, null, type);
}
如果您想要真正的并行性,则应使用Task.Run
(.NET 4.5)或Task.Factory.StartNew
(.NET 4)。