为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
明月笑刀无情 2022-12-24 11:01:55
我有大量数据,我需要每 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);        }    }
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

最直接的解决方案是添加lock到您的代码中。这将防止任何竞争条件,也会使您的代码变慢一点,因为它会在资源正在使用时阻塞线程。


你可以像这样使用它:


// add new lock object

object lockObject = new object();

FileStream fs = null;

int filecount = 0;

long a = 1000000000000000;



private void WriteINFile()

{

    string sen = " write in file ";


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

    {

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

        lock (lockObject)

        {

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

        }

    }

}



private void Commitzfile()

{

    lock(lockObject)

    {

        fs.Flush();

        fs.Close();

        filecount++;

        initialiseFile(filecount);

    }

}

我建议您阅读以下有关锁定语句的文档


更新

在并发编程中有许多问题需要考虑。其中之一是资源管理。通常该问题与Dining philosophers problem一起出现。主要问题发生在尝试由多个进程/线程使用资源时,但该资源一次只能由一个进程/线程使用。在您的情况下,它是 FileStream,因为一个线程一直试图写入它,而在另一个线程上它已关闭并已更改。您可以看到,在某些情况下,可能会发生一个关闭流而另一个仍在尝试同时写入的情况。要克服这个问题,您需要确保资源一次只能由一个线程访问。执行此操作的一种工具是锁定语句。

其他要记住的事情:

  • 死锁。

  • 有多少并发线程值得同时运行。

希望这个简短的总结能有所帮助。如果您需要更多信息,请随时提出新问题(或查找是否已有问题)。


查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 70 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号