C# 并行使用多个Stream.BeginWrite是否线程安全?

C# 并行使用多个Stream.BeginWrite是否线程安全?,c#,stream,C#,Stream,我有一个文件,我要填写,所以我想如果它更好地同时做 注意事项: 我同时从多台计算机获取文件 每次打StartWrite之前我都会设置位置。->每次使用前是否必须将其锁定 这是好的苏洛蒂安吗?有更好的吗 顺便说一句,Stream.Flush()是什么 谢谢。试图同时对同一个流执行多个写操作是毫无意义的 底层系统一次只能写入文件中的一个位置,因此即使异步写入方法支持多线程,写入仍然会被阻止 只需定期写入文件,并使用锁定,以便一次只有一个线程写入文件。尝试同时对同一流执行多个写入操作是毫无意义的 底层

我有一个文件,我要填写,所以我想如果它更好地同时做

注意事项:

  • 我同时从多台计算机获取文件
  • 每次打StartWrite之前我都会设置位置。->每次使用前是否必须将其锁定
  • 这是好的苏洛蒂安吗?有更好的吗

    顺便说一句,Stream.Flush()是什么


    谢谢。

    试图同时对同一个流执行多个写操作是毫无意义的

    底层系统一次只能写入文件中的一个位置,因此即使异步写入方法支持多线程,写入仍然会被阻止


    只需定期写入文件,并使用锁定,以便一次只有一个线程写入文件。

    尝试同时对同一流执行多个写入操作是毫无意义的

    底层系统一次只能写入文件中的一个位置,因此即使异步写入方法支持多线程,写入仍然会被阻止


    只需定期写入文件,并使用锁定,以便一次只有一个线程写入文件。

    原则上这是不安全的,因为即使您的流是线程安全的,您仍然必须以非原子方式设置位置和写入

    本机Windows文件API支持这一点,.NET不支持。Windows完全能够并发IO到同一个文件(如果Windows不支持,SQL Server将如何工作?)


    我建议您只需为每个线程使用一个写入
    FileStream

    原则上这是不安全的,因为即使您的流是线程安全的,您仍然必须以非原子方式设置位置并进行写入

    本机Windows文件API支持这一点,.NET不支持。Windows完全能够并发IO到同一个文件(如果Windows不支持,SQL Server将如何工作?)


    我建议每个线程只使用一个编写
    文件流

    不,这在概念上是错误的。Stream(我想你指的是一个类)是一个抽象类。当您实例化一个对象时,您使用的是许多子类之一

    假设任何关于子类的内容都是错误的方法,因为:

    a) 有人可能会跟踪您对代码进行修改,而看不到实际的子类实现的功能。 b) 可能性较小,但实现可能会改变。例如,如果有人在Mono框架上安装了您的代码,该怎么办

    如果您正在使用FielestRAM类,请考虑在两个(或多个)FiestestRAM对象上创建与要写入的参数集相同的基础文件。通过这种方式,您可以指定可以同时写入,但每个流都有自己的位置指针


    更新:直到现在我才看到你的评论“每台计算机都给我发送一个包含开始索引、结束索引和字节[]的部件”。实际上,在这种情况下,多个文件流应该可以正常工作

        void DataReceived(int start, byte[] data)
        {
            System.IO.FileStream f = new System.IO.FileStream("file.dat", System.IO.FileMode.Open, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
            f.Seek(start, System.IO.SeekOrigin.Begin);
            f.Write(data, start, data.Length);
            f.Close();
        }
    

    不,这在概念上是错误的。Stream(我想你指的是一个类)是一个抽象类。当您实例化一个对象时,您使用的是许多子类之一

    假设任何关于子类的内容都是错误的方法,因为:

    a) 有人可能会跟踪您对代码进行修改,而看不到实际的子类实现的功能。 b) 可能性较小,但实现可能会改变。例如,如果有人在Mono框架上安装了您的代码,该怎么办

    如果您正在使用FielestRAM类,请考虑在两个(或多个)FiestestRAM对象上创建与要写入的参数集相同的基础文件。通过这种方式,您可以指定可以同时写入,但每个流都有自己的位置指针


    更新:直到现在我才看到你的评论“每台计算机都给我发送一个包含开始索引、结束索引和字节[]的部件”。实际上,在这种情况下,多个文件流应该可以正常工作

        void DataReceived(int start, byte[] data)
        {
            System.IO.FileStream f = new System.IO.FileStream("file.dat", System.IO.FileMode.Open, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
            f.Seek(start, System.IO.SeekOrigin.Begin);
            f.Write(data, start, data.Length);
            f.Close();
        }
    


    哇!你真的在找麻烦;)你让它看起来像我试图打破奥巴马的电子邮件。描述问题更好。你怎么知道该放在什么位置?这东西有多大?是的,你必须锁门。因此,甚至不要尝试使用异步。每台计算机都会向我发送一个包含开始索引、结束索引和字节[]的部分。还有什么吗?一次只能向文件写入一个东西。即使Stream.BeginWrite支持一次写入多个线程,您也会被文件系统阻止,并最终降低被阻止线程之间的性能切换。哇。。。你真的在找麻烦;)你让它看起来像我试图打破奥巴马的电子邮件。描述问题更好。你怎么知道该放在什么位置?这东西有多大?是的,你必须锁门。因此,甚至不要尝试使用异步。每台计算机都会向我发送一个包含开始索引、结束索引和字节[]的部分。还有什么吗?一次只能向文件写入一个东西。即使Stream.BeginWrite支持一次写入多个线程,您也会被文件系统阻止,并最终降低在被阻止线程之间切换的性能。如果您认为它很糟糕,您能详细介绍一下我是如何做到这一点的吗?有什么想法吗?好的,每当你从“计算机”收到一个包时,按照我上面描述的创建一个FileStream对象,以正确的偏移量写入它,然后关闭句柄。您可以在单独的线程或单独的应用程序中执行此操作,操作系统将独立地写入同一个文件。在按钮行,它是并行的还是一次写入一个文件?检查我刚才添加到答案中的代码:如果此函数是从多个线程(甚至进程)调用的,它将被写入OK。最后,这实际上取决于您要写入的介质:物理磁盘的写入方式与SSD不同,但就.NET而言,这是并行的。等等,您的意思是为每个线程创建一个文件流吗?它就像[localThread]的位置:P好主意。如果你认为它很糟糕,你能写更多关于我是如何做到的吗?知道吗?好吧,什么时候