簡體   English   中英

為什么 Stream.CopyTo 不直接寫入文件?

[英]Why is Stream.CopyTo not writing directly to a file?

此操作塊連接到帶有簽名的轉換塊var getStream = new TransformBlock<FileChunk, Tuple<Task<HttpResponseMessage>, FileChunk>>但是,stream 不直接寫入提供的文件。 出於某種原因,我認為它仍在緩存到 memory。 任務是元組初始化為client.SendAsync(request, HttpCompletionOption.ResponseContentRead, CancellationToken.None);

var writeStream = new ActionBlock<Tuple<Task<HttpResponseMessage>, FileChunk>>(async task =>
{
    using (var streamToRead = await task.Item1.Result.Content.ReadAsStreamAsync())
    {
        using (var fileToWriteTo = File.Open(task.Item2._tempfilename,
            FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
        {
            await task.Item1.Result.Content.CopyToAsync(fileToWriteTo).ContinueWith(task1 =>
            {
                var s = new FileChunk();
                Interlocked.Add(ref TasksDone, 1);
                asyncTasks.TryDequeue(out s);
            }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion,
                TaskScheduler.Current);
        }
    }
}, new ExecutionDataflowBlockOptions
{
    BoundedCapacity = Environment.ProcessorCount, // Cap the item count
    MaxDegreeOfParallelism = Environment.ProcessorCount, // Parallelize on all cores
});

關於如何解決這個問題的任何建議? 另外,我假設它首先緩存到 memory 因為文件大小不會在刷新時更新或增加,而是一次全部更新。

我建議分離人工的ContinueWith延續,並直接await CopyToAsync操作。 使用您當前的設置,如果出現問題,您將不會獲得任何信息,因為如果出現異常, TaskContinuationOptions.OnlyOnRanToCompletion將導致繼續被取消,並且 TPL 數據流塊忽略OperationCanceledException s。

這是我的建議:

var writeStream = new ActionBlock<Tuple<Task<HttpResponseMessage>, FileChunk>>(async task =>
{
    using (var streamToRead = await task.Item1.Result.Content.ReadAsStreamAsync())
    {
        using (var fileToWriteTo = File.Open(task.Item2._tempfilename,
            FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
        {
            await task.Item1.Result.Content.CopyToAsync(fileToWriteTo);
        }
        Interlocked.Add(ref TasksDone, 1);
        asyncTasks.TryDequeue(out var s);
    }
});

我還建議考慮將Tuple替換為ValueTuple ,以獲得簡化的語法並防止冗余分配:

var writeStream = new ActionBlock<(Task<HttpResponseMessage>, FileChunk)>(async task =>

最后我應該指出,我對嘗試同時在同一個物理磁盤中寫入多個文件的過程的性能特征持懷疑態度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM