在我的程序中,我收到一些数据,我必须将其保存到一个文件(一个或多个),数据顺序非常重要,所以它应该像先到先保存一样。
最后,我得到一个信号,表示此时不再有数据可用,我必须关闭所有打开的文件,我该如何处理它,我的意思是我怎样才能确保所有线程都完成了他们的工作所以,我可以关闭文件。
我正在使用ManualResetEvent
来控制数据的顺序,以便下一个帖子等待上一个线程完成它的工作。
以下是我的代码示例,我需要指南以非常有效的方式完成同样的工作,我怎么知道所有线程都完成了他们的工作。
class Program
{
static StreamWriter _fileStream;
static void Main(string[] args)
{
_fileStream = File.CreateText(@"D:\HelloThread.txt");
ManualResetEvent currentEvent = new ManualResetEvent(true);
ManualResetEvent nextEvent = new ManualResetEvent(false);
int length = 60;
Data data = null;
Console.WriteLine("Writing started...");
for (int i = 0; i < length; i++)
{
data = new Data { CurrentEvent = currentEvent, Number = i, NextEvent = nextEvent };
ThreadPool.QueueUserWorkItem(PrintMsg, data);
currentEvent = nextEvent;
nextEvent = new ManualResetEvent(false);
}
Console.ReadLine();
}
private static void CloseAll()
{
Console.WriteLine("Requested to close all...");
Console.WriteLine("Done with the writing...");
}
private static object _lockObj = new object();
private static void PrintMsg(object state)
{
Data data = state as Data;
data.CurrentEvent.WaitOne();
string msg = "Hello times...";
for (int j = 0; j < 5; j++)
{
_fileStream.WriteLine(msg + data.Number);
// Console.WriteLine(msg + data.Number);
}
data.NextEvent.Set();
}
}
public class Data
{
public ManualResetEvent CurrentEvent { get; set; }
public ManualResetEvent NextEvent { get; set; }
public int Number { get; set; }
}
答案 0 :(得分:3)
听起来您正在描述一个应用程序管道,其中有多个线程,每个线程都在一个工作项的单独部分上工作。例如,一个线程可能正在进行输入,一个线程正在执行进程,一个线程正在执行输出。
通常,您可以通过创建多个队列来处理此问题。假设你有这三个主题。输入线程读取记录并将其放入输入队列。处理线程读取输入队列,处理项目,并将结果放入输出队列。然后输出线程读取输出队列并将数据写入需要的位置。
这确保以正确的顺序处理和编写工作项,但允许所有线程同时工作。
使用BlockingCollection,您可以让线程在队列中执行非忙等待。此外,当输入线程完成读取时,它可以调用队列上的CompleteAdding
以表示没有更多工作项。当处理线程读取队列时,它可以检查IsCompleted
属性以确定是否所有项都已完成,从而退出。读取输出队列时输出线程也是一样。
有关使用BlockingCollection
的一些简单示例,请参阅http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=821。
如果你不能使用BlockingCollection
,那么你必须在Queue<T>
周围包装一个并发层。