首页 > 解决方案 > C#:FileStream.ReadByte() 是多线程友好函数吗?

问题描述

所以我有 16 个线程同时运行这个方法:

    private void Work()
    {
        int currentByte;
        char currentChar;

        try
        {
            while (true)
            {
                position++;
                currentByte = file.ReadByte();
                currentChar = Convert.ToChar(currentByte);

                entries.Add(new Entry(currentChar));
            }
        }
        catch (Exception) { }
    }

然后我又多了一个线程运行这个方法:

    private void ManageThreads()
    {
        bool done;

        for(; ; )
        {
            done = !threads.Any(x => x.IsAlive == true);//Check if each thread is dead before continuing
            if (done)
                break;
            else
                Thread.Sleep(100);
        }
        PrintData();
    }

这是问题所在:PrintData 方法只是将“条目”列表中的所有内容打印到文本文件中。即使使用相同的输入文件,每次运行程序时,该文本文件都会有所不同。当谈到多线程应用程序时,我有点菜鸟,所以请随意提出批评。

标签: c#multithreadinglinqfilestream

解决方案


一般来说,除非 type 在其文档中明确调用线程安全,否则您应该假设它不是线程安全的*。.Net 中的流没有这样的部分,应该被视为非线程安全的——使用适当的同步(即锁)来保证每次从一个线程访问每个流。

对于文件流,还有另一个问题 - 操作系统级别的文件对象可能会从其他线程更新 -FileStream试图通过检查其内部状态是否与操作系统状态匹配来缓解它 - 请参阅MSDN 上的FileStream:remarks部分。

如果你想要线程安全的流,你可以尝试使用C#Synchronized中所示的方法,是否有“线程安全”流这样的东西?.

请注意,无论流是否是线程安全的,您在帖子中的代码都会产生随机结果。流的线程安全只会保证所有字节都显示在输出中。如果使用非线程安全流,则根本无法保证,并且某些字节可能会多次显示,一些被跳过和任何其他行为(崩溃,部分读取,...)都是可能的。


*线程安全,如“无论是从一个线程还是多个线程调用,实例的内部状态都是一致的”。这并不意味着从不同线程调用任意方法会导致有用的行为。


推荐阅读