gpt4 book ai didi

c# - 如何保证在多线程中写入文件有异常?

转载 作者:行者123 更新时间:2023-11-30 21:48:47 24 4
gpt4 key购买 nike

这是一个简化的例子

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new Thread(() => Method1()).Start();
new Thread(() => Method2()).Start();
Console.Read();
}

private static void Method1()
{
using (StreamWriter sw = new StreamWriter(@"h:\data.txt"))
{
int i = 100000000;
while (true)
{
Thread.Sleep(100);
sw.WriteLine(i);
i++;
}
}
}

private static void Method2()
{
Thread.Sleep(6000);
throw null;
}
}
}

如果异常过早发生在另一个线程中,StreamWriter 不会将数据写入文件。发生异常时文件data.txt为空。

我试了一下这种情况并找到了一些解决方法:

  1. 如果我增加异常线程的 sleep 间隔(并减少写入文件的间隔),文件将充满数据。这不是一个选择,因为我不知道什么时候会发生异常。

  2. 由于之前的解决方法,我可以减小流写入器的缓冲区大小。但如果我将它设置得太小,它似乎不起作用 - 例如,这段代码

    FileStream fs = new FileStream(@"h:\data.txt", FileMode.Create);

    使用 (StreamWriter sw = new StreamWriter(fs, Encoding.Default, 10))

不起作用,因为只有当大约 385 个整数在缓冲区中等待写入文件时,才会发生第一次写入操作。

  1. 如果我在异常发生前关闭编写器,文件将被填充。但这不是一个好的选择——我必须每秒写入文件 1 到 10 次。如此频繁地打开和关闭 writer 不是一个好主意,是吗?

  2. 我可以像这样捕获异常

    私有(private)静态无效方法 2(){

    try
    {
    Thread.Sleep(6000);
    throw null;
    }
    catch
    {
    Console.WriteLine("Exception!");
    }

一切都会好起来的——应用程序不会终止,文件会一个包一个包地填充。但事实并非如此——我无法控制异常发生的时间和地点。我尝试在所有地方使用 try-catch,但我可能会遗漏一些东西。

所以情况是:StreamWriter的buffer没有满,另外一个线程发生了exception,没有被catch,所以应用会被终止。如何不丢失这些数据并将其写入文件?

最佳答案

据我了解您的情况,您假设某处存在错误并且进程可能随时终止。您希望保存尽可能多的数据。

您应该能够在 StreamWriter 上调用 Flush。这会将数据推送到操作系统。如果您的进程终止,数据最终将由操作系统写入。

如果由于某种原因您无法说服 StreamWriter 实际刷新,您可以使用 FileStream 并写入(伪代码:fileStream.Write(Encoding. GetBytes(myString)))。然后您可以刷新 FileStream 或使用大小为 1 的缓冲区。

当然,如果您首先阻止进程被终止,那是最好的。这通常是直接使用 Task 而不是使用原始 Thread

关于c# - 如何保证在多线程中写入文件有异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37436780/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com