当我尝试使用线程重命名我的文件名并关闭并刷新 FileStream 时

我有大量数据,我需要每 5 秒制作一次“.txt”文件,然后在新创建的“.txt”文件中写入下一个数据,但是当我尝试使用定时器线程时,程序运行正常但是一段时间后,它将通过异常无法访问已关闭的文件。请在我的代码中帮助我,并建议我必须做什么。


public class Program

    {

        public static void Main(string[] args)

        {

            Service s = new Service();

            s.init();

        }

    }



    class Service

    {

        FileStream fs = null;

        int filecount = 0;

        long a = 1000000000000000;

      // int j = 0;


        public void  init()

        {

            initialiseFile(filecount);

            timer();

            WriteINFile();

        }


        private void initialiseFile( int filecount)

        {


                fs = File.Create("C:\\Users\\yogesh.ghonate\\source\\repos\\ConsoleApp3\\ConsoleApp3\\NewFolder1\\Index_" + filecount + ".txt");        

        }

        private void WriteINFile()

        {

            string sen = " write in file ";


                for (int i = 0; i < a; i++)

                {

                    Byte[] title = new UTF8Encoding(true).GetBytes(sen);


                    fs.Write(title, 0, title.Length);

                }

        }


        public void timer()

        {

            System.Timers.Timer th = new System.Timers.Timer();

            th.Interval = 5000;

            th.Elapsed += new ElapsedEventHandler(run);

            th.Start();         

            run(th, null);

        }


        public void run(object state, ElapsedEventArgs e)

        {

            Commitzfile();

        }


        private void Commitzfile()

        {


            //Stopwatch stopwatch = new Stopwatch();

            //stopwatch.Start();

            fs.Flush();

            fs.Close();

            // fs.Dispose();

            //stopwatch.Stop();

            filecount++;

            initialiseFile(filecount);


        }

    }


明月笑刀无情
浏览 71回答 1
1回答

弑天下

最直接的解决方案是添加lock到您的代码中。这将防止任何竞争条件,也会使您的代码变慢一点,因为它会在资源正在使用时阻塞线程。你可以像这样使用它:// add new lock objectobject lockObject = new object();FileStream fs = null;int filecount = 0;long a = 1000000000000000;…private void WriteINFile(){&nbsp; &nbsp; string sen = " write in file ";&nbsp; &nbsp; for (int i = 0; i < a; i++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Byte[] title = new UTF8Encoding(true).GetBytes(sen);&nbsp; &nbsp; &nbsp; &nbsp; lock (lockObject)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fs.Write(title, 0, title.Length);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}…private void Commitzfile(){&nbsp; &nbsp; lock(lockObject)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; fs.Flush();&nbsp; &nbsp; &nbsp; &nbsp; fs.Close();&nbsp; &nbsp; &nbsp; &nbsp; filecount++;&nbsp; &nbsp; &nbsp; &nbsp; initialiseFile(filecount);&nbsp; &nbsp; }}我建议您阅读以下有关锁定语句的文档更新在并发编程中有许多问题需要考虑。其中之一是资源管理。通常该问题与Dining philosophers problem一起出现。主要问题发生在尝试由多个进程/线程使用资源时,但该资源一次只能由一个进程/线程使用。在您的情况下,它是 FileStream,因为一个线程一直试图写入它,而在另一个线程上它已关闭并已更改。您可以看到,在某些情况下,可能会发生一个关闭流而另一个仍在尝试同时写入的情况。要克服这个问题,您需要确保资源一次只能由一个线程访问。执行此操作的一种工具是锁定语句。其他要记住的事情:死锁。有多少并发线程值得同时运行。希望这个简短的总结能有所帮助。如果您需要更多信息,请随时提出新问题(或查找是否已有问题)。
打开App,查看更多内容
随时随地看视频慕课网APP