3

Codeplex でダウンロード マネージャー タイプのプロジェクトを調べていたところ、 http ://nthdownload.codeplex.com/ に出会いました。

AddDownloads以下にリストされているようなメソッドに出くわしたコードをブラウズします。

AddDownloads_downloadQueue.AddDownloads タスクを開始し、タスクを続行しviewMaintenanceTaskます。これら 2 つのタスクとダウンストリームで発生するメソッドと物事を見ると、すべてが同期しているように見えます。

また、このブログ投稿「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;
4

1 に答える 1

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.RunNET 4.5) またはTask.Factory.StartNew(.NET 4) を使用する必要があります。

于 2012-11-03T19:19:47.193 に答える