C# 将同步或异步方法作为任务使用

C# 将同步或异步方法作为任务使用,c#,async-await,C#,Async Await,我在看codeplex上的下载管理器类型项目时,偶然发现了这个项目: 浏览我在AddDownloads等方法中运行的代码,如下所示: AddDownloads启动_downloadQueue.AddDownloads任务并继续执行viewMaintenanceTask任务。如果你看一下这两个任务中发生的方法和事情,你会发现一切都是同步的 在阅读这篇博文的同时,我还试图了解在TaskCompletionSource中包装同步方法的好处(如果有的话)。这是因为它给API使用者提供了在单独线程上启动

我在看codeplex上的下载管理器类型项目时,偶然发现了这个项目:

浏览我在
AddDownloads
等方法中运行的代码,如下所示:

AddDownloads
启动_downloadQueue.AddDownloads任务并继续执行
viewMaintenanceTask
任务。如果你看一下这两个任务中发生的方法和事情,你会发现一切都是同步的

在阅读这篇博文的同时,我还试图了解在
TaskCompletionSource
中包装同步方法的好处(如果有的话)。这是因为它给API使用者提供了在单独线程上启动任务的选项,还是仅仅因为您希望将该方法作为
任务使用。封装在
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中的同步方法是否受益于并行处理

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
不会以任何方式、形状或形式创建新线程

您在底部给出的代码是毫无意义的——当方法返回时,任务将已经完成(或出现故障)。只有当您必须使用任务时,它才有任何用处。我可能会把它改成:

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;
}

如果您想要真正的并行性,应该使用(.NET 4.5)或(.NET 4)。

因此,在这两个示例中,实际上没有任何理由在TCS中封装代码。等待TCS中封装的synchronouse代码与调用它与您通常调用的方法相同吗?@DerekBeattie:如果TCS已经完成,它们基本上是等价的。有一些细微的差别,但我怀疑它们是否适用于这里。
public static async Task<object> Deserialize(Model model, Stream stream,
                                             Type type)
{
    return model.Deserialize(stream, null, type);
}