【发布时间】:2015-08-29 09:33:28
【问题描述】:
我开发了一个应用程序,将 10000 行 lorem ipsum 保存在磁盘上的 .txt 文件中。我使用 StreamWriter 来实际编写这些行,并使用 ThreadPool 将计算过程分配给可用的线程/内核。
保存速度非常快,即使有 100 万行,但问题是,并非所有行都被保存,最后一行被部分保存。当我关闭程序时,由于某种原因它再次写入文件。
我有以下字符串:
String loremipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
剩下的代码是:
private StreamWriter writer = new StreamWriter("loremipsum.txt");
private Object lockObject = new Object();
// Button that initiates the process
private void btnSave_Click(object sender, RoutedEventArgs e)
{
for (int i = 1; i <= 10000; i++)
{
ThreadPool.QueueUserWorkItem(state =>
{
SaveFile(writer, loremipsum);
});
}
}
private void SaveFile(StreamWriter w, String text)
{
lock (lockObject)
{
w.WriteLine(text);
}
}
由于 StreamWriter 不是线程安全的,我使用的是锁定对象。
如果我在运行程序的情况下打开 .txt 文件,它只有 9998 行,最后一行不完整。
如果我关闭程序,它会再次重写文件,添加所有行,但最后一行仍然不完整。为什么会这样?
我想这些行被部分保存了,因为 ThreadPool 的线程需要一些时间来完成它们的工作。我对么?如果是这样,我该如何实现?
【问题讨论】:
-
你是否使用了 Flush() 然后 Close()。像所有流类一样,streamwriter 缓冲写入数据,并且直到缓冲区已满才真正写入文件。通常对于流,最后一个缓冲区不会被写入,使用 Flush() 可以解决问题。
-
没有任何理由可以为此使用多个线程。这里没有 CPU 绑定操作,一次只能写一行。只需将所有 10,000 行写在一个线程中,完成后不要忘记处理
StreamWriter。 -
@CharlesMager 我不知道,但是使用 ThreadPool 执行此操作会导致操作非常快,我尝试仅使用一个线程编写,但它需要 10 倍的时间。
-
那么它可能没有按照您的想法进行。由于您的锁定,所有内容都必须同步,因此即使使用多个线程,一次也只能写入一行。加上开销。这应该更慢(也是一个坏主意)。
-
完成后如何检查?您的事件处理程序几乎会立即返回,但您不知道所有任务何时执行完毕。
标签: c# multithreading threadpool streamwriter