Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# StreamWriter创建零字节文件_C#_.net - Fatal编程技术网

C# StreamWriter创建零字节文件

C# StreamWriter创建零字节文件,c#,.net,C#,.net,我有一个任务,从阻塞集合中读取字符串,并将其写入文件。问题是,在创建文件时,任务完成后文件的大小为0字节 在调试时,我看到从阻塞集合中检索到非空行,流编写器被包装在一个using块中 对于调试,我抛出了一个不需要的刷新,并将这些行写入控制台。从阻止集合中读取的文本有100个非空行 // Stuff is placed in writeQueue from a different task BlockingCollection<string> writeQueue = new Bl

我有一个任务,从阻塞集合中读取字符串,并将其写入文件。问题是,在创建文件时,任务完成后文件的大小为0字节

在调试时,我看到从阻塞集合中检索到非空行,流编写器被包装在一个using块中

对于调试,我抛出了一个不需要的刷新,并将这些行写入控制台。从阻止集合中读取的文本有100个非空行

// Stuff is placed in writeQueue from a different task  
BlockingCollection<string> writeQueue = new BlockingCollection<string>();

Task writer = Task.Factory.StartNew(() => 
{
    try
    {
        while (true)
        {
            using (FileStream fsOut = new FileStream(destinationPath, FileMode.Create, FileAccess.Write))
            using (BufferedStream bsOut = new BufferedStream(fsOut))
            using (StreamWriter sw = new StreamWriter(bsOut))
            {
                string line = writeQueue.Take();
                Console.WriteLine(line); // Stuff is written to the console
                sw.WriteLine(line);
                sw.Flush(); // Just in case, makes no difference
            }
        }
    }
    catch (InvalidOperationException)
    {
        // We're done.
    }
});
//从不同的任务将内容放入writeQueue
BlockingCollection writeQueue=新BlockingCollection();
任务编写器=Task.Factory.StartNew(()=>
{
尝试
{
while(true)
{
使用(FileStream fsOut=newfilestream(destinationPath,FileMode.Create,FileAccess.Write))
使用(BufferedStream bsOut=新的BufferedStream(fsOut))
使用(StreamWriter sw=新StreamWriter(bsOut))
{
string line=writeQueue.Take();
Console.WriteLine(行);//将内容写入控制台
西南写入线(行);
sw.Flush();//以防万一,没有区别
}
}
}
捕获(无效操作异常)
{
//我们结束了。
}
});
在调试程序中,我看到程序以有序的方式终止。没有未处理的异常


这里可能出了什么问题?

每次运行循环时都会重新创建文件。将
FileMode.Create
更改为
FileMode.Append
,它将保留您以前在其上写入的值


另外,如果这是消费者-生产者解决方案,那么使用异常来检测您应该停止是一种非常糟糕的做法,您可以通过让生产者设置一个线程安全标志变量来轻松地做得更好,该变量表示它已经完成了工作,并且不会生成任何其他内容。

中使用
s移动
,而在
中使用
将比
高效得多。Append
。是的,不确定他为什么这样做。哎呀。这就是我一天18小时的收获:-)谢谢。事实上,
BlockingCollection
已经有一个布尔属性,表示它不会产生任何其他内容:
IsCompleted
@phoog:True,但如果您检查该属性,仍然可以得到InvalidOperationException,它是false,该线程被调用AddingComplete的线程抢占,原始线程恢复。您仍然必须处理该异常。如果我有许多小的阻塞集合,我可能会检查标志以提高效率,并且仍然处理边缘情况的异常。因为我不是这样,所以我选择了MSDN示例中的模式。不要将无效操作异常视为您已完成阅读或写作的标志。这将隐藏真正的bug。也不要刷新,因为它确实会产生(负面)差异。@usr:实际上,您必须处理InvalidOperationException。即使检查已完成,也可以抢占该任务,并在该检查之后将阻塞集合标记为完成。还是我遗漏了什么?此外,这也是MSDN上的模式(并不是说它一定很好。毕竟MSDN在其示例中几乎从不处理IDisposable资源,等等)。您可以使用BlockingCollection.GetConsumingEnumerable。在任何cas中,我都会围绕着这条线进行尝试捕捉,并努力安排一切,以便只保护这个接听呼叫。