2013-05-28 81 views
1

我有一个事件触发多次。每次射击都会产生一个处理输入的线程,并且这些处理必须是顺序的。C#:管理线程等待队列

这是代码:

void TcpClient_DataRead(object sender, DataReadEventArgs e) 
    { 
     //the first stops the other ones 
     this.parsingXML.WaitOne(); 
     //processing the string 
     string pop = Encoding.ASCII.GetString(e.Data); 
     BufferizeXML(pop); 
     //restoring execution 
     this.parsingXML.Set(); 
    } 

在这里,我试图让其他线程等待和前一个执行结束后恢复,但这种方法恢复所有的等待线程。

是否有一个管理等待线程队列的方法?

+2

听起来像一个可爱的TPL DataFlow工作:http://msdn.microsoft.com/en-us/library/hh228603.aspx – spender

回答

5

这是一个典型的情况,您可以使用发布 - 消费者模式。 您可以使用Queue<T>ConcurrentQueue<T>排队事件,然后让一个线程出队并执行实际处理。你只需要一个线程,因为你说他们需要按顺序执行,这将避免创建线程的时间。如果你不能(主要是因为你被迫使用旧版本的框架)使用并发版本,那么请注意你必须锁定队列访问的事实。

+2

+1,是的,也避免了线程微观管理,新手总是出错,而那些有更多经验的人从不尝试。不幸的是,OP似乎已经阅读了许多着名的“Introduction to Threads”书籍/网站,它们似乎总是以不断创建线程并等待它们以join()或其他方式终止为开始。正如我以前多次发表的那样,这些作者应该与利害关系,他们的书籍/打印输出堆放在一起,并使用火炬。 –

0

当应用程序初始化,创建并发队列,启动数据读取任务并在其后绑定事件处理程序时启动任务。

ConcurrentQueue<DataReadEventArgs> list; 
Init() 
{ 
    var list = new ConcurrentQueue<DataReadEventArgs>(); 
    Task.Factory.StartNew(()=>DataRead()); 
    OnTcpClientDataRead += TcpClient_DataRead; 
} 

//发布

void TcpClient_DataRead(object sender, DataReadEventArgs e) 
{ 
    list.Enqueue(e); 
} 

一个始终运行的作业在队列中的所有数据处理BufferizeXml,如果列表为空它需要一秒钟的暂停和再继续//消费器

void DataRead() 
{ 
    while(true) 
    { 
    if (list.Count ==0) 
    Thread.Sleep(1000); 

    string pop; 
    list.TryDequeue(out pop); 
    Encoding.ASCII.GetString(pop); 
    BufferizeXML(pop); 
    } 
} 

你可以放一些变量,让while循环检查它是否打破迭代。

+0

如果TcpClient_DataRead被2个线程同时访问会发生什么?在这种情况下不会工作,您需要在开始时初始化它。 –

+1

@FelixK。我更改了代码。 –