c# - 使用 FileStream.WriteAsync() 时,再次调用该方法时会发生什么

标签 c# asynchronous async-await filestream

我正在将视频流录制到磁盘。为此,我使用以下代码:

private async Task SaveToFile(IntPtr data, Int32 size)
{
    if (_FileStream == null) return;
    Byte[] buf = new Byte[size];
    Marshal.Copy(data, buf, 0, size);
    //dont await here - just continue
    _FileStream.WriteAsync(buf, 0, size);
}

到目前为止,它似乎没有问题。我只想确认的是,如果在上一次迭代完成之前调用此方法会发生什么情况。

您会注意到我没有等待 WriteAsync() 调用。我不确定这是否正确,但我正在使用的 API 声明在此方法内将操作保持在最低限度,以免在 API 内部阻止回调。这似乎是正确的做法,只需将数据传递给流,然后立即返回。

有人可以确认如果最后一次 WriteAsync() 调用没有完成,我再次调用 WriteAsync() 会发生什么吗?或者我应该 awaitWriteAsync() 调用?

编辑: 我还没有使用上述方法遇到异常,所以我想我的最后一个问题是从外部 DLL 回调内部使用 WriteAsync() 时是否有任何影响? DLL 是第三方 Directshow 组件。我无法验证它在内部是如何工作的,但它只是通过回调向我提供数据,我将数据保存到文件流中。

最佳答案

异步重叠 WriteAsync 操作没有任何问题,只要它们写入文件的不同、非重叠段即可:

using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var tempFile = System.IO.Path.GetTempFileName();
            Console.WriteLine(tempFile);

            var fs = new System.IO.FileStream(
                tempFile, 
                System.IO.FileMode.Create, 
                System.IO.FileAccess.ReadWrite, 
                System.IO.FileShare.ReadWrite, 
                bufferSize: 256,
                useAsync: true);

            fs.SetLength(8192);

            var buff1 = Enumerable.Repeat((byte)0, 2048).ToArray();
            var buff2 = Enumerable.Repeat((byte)0xFF, 2048).ToArray();

            try
            {
                fs.Seek(0, System.IO.SeekOrigin.Begin);
                var task1 = fs.WriteAsync(buff1, 0, buff1.Length);

                fs.Seek(buff1.Length, System.IO.SeekOrigin.Begin);
                var task2 = fs.WriteAsync(buff2, 0, buff2.Length);

                Task.WhenAll(task1, task2).Wait();
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}

在低层次上,这一切都归结为 WriteFile具有非空 LPOVERLAPPED lpOverlapped 的 API,这是 Windows API 中支持的场景。

如果写入重叠,您仍然不会看到错误,但写入会竞争,最终结果可能无法预测。

关于c# - 使用 FileStream.WriteAsync() 时,再次调用该方法时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28623141/

相关文章:

typescript - async/await 语法在 TypeScript 中如何工作?

c# - 在 VS 2008 中运行单元测试项目时出现 DisconnectedContext 错误

c# - Xamarin TimeZoneInfo.GetUtcOffset 抛出 NotImplementedException

javascript - Webworker回调后返回结果

angular - typescript /Angular : Wait for sequentially delayed async tasks to be completed

javascript - 您应该在异步函数中等待返回值吗?

c# - 加密 Unity c# 标注到 Node js 服务器

c# - 如何处理 Actor 内部的异常?

java - 将第一个 CompletableFuture 的结果传递给链上的其他 CompletableFuture

c# - 为什么 Elvis (?.) 运算符不适用于异步等待?