我有一个应用程序,其中多个线程必须等待事件以指示列表中的新数据可用。我的期望是我可以在每个线程中使用AutoResetEvent,WaitOne,然后在数据可用时设置事件。
但是,因为它是自动重置,所以第一个线程清除事件并且不释放其他线程。现在我可以把它作为一个手动重置并实现一个计数器,但我的感觉是这是一个常见的问题,因此必须有一个标准的方法来做到这一点,但搜索文档我找不到。< / p>
有任何帮助吗?以下是一些不会释放所有线程的示例代码:
static AutoResetEvent eve = new AutoResetEvent(false);
static void Main(string[] args)
{
var threads = new List<Thread>();
for (int i = 0; i < 10; ++i)
{
int iCopy = i;
var t = new Thread(() => thread(iCopy));
threads.Add(t);
t.Start();
}
Console.WriteLine("Pausing");
Thread.Sleep(5000);
eve.Set();
foreach (var t in threads) t.Join();
Console.WriteLine("All done");
Console.ReadKey();
}
static void thread(int n)
{
eve.WaitOne();
Console.WriteLine("Thread {0}", n);
}
答案 0 :(得分:1)
只需使用ManualResetEvent代替AutoRestEvent。不需要反击。我试过,下面的代码就是代码。
static ManualResetEvent eve = new ManualResetEvent(false);
static void Main(string[] args)
{
var threads = new List<Thread>();
for (int i = 0; i < 10; ++i)
{
int iCopy = i;
var t = new Thread(() => thread(iCopy));
threads.Add(t);
t.Start();
}
Console.WriteLine("Pausing");
Thread.Sleep(5000);
eve.Set();
foreach (var t in threads) t.Join();
Console.WriteLine("All done");
Console.ReadKey();
}
static void thread(int n)
{
eve.WaitOne();
Console.WriteLine("Thread {0}", n);
}
答案 1 :(得分:0)
我有一个应用程序,其中多个线程必须等待事件以指示列表中的新数据可用。我的期望是我可以在每个线程中使用AutoResetEvent,WaitOne,然后在数据可用时设置事件。
你有一点XY Problem,但幸好你包括了你的&#34; X&#34;是(一旦可用,让线程从列表中获取新数据)。
基于您的描述,我认为您最好使用BlockingCollection
,您可以根据需要调整尽可能多的线程,只要数据可用,它们都会阻塞直到新数据可用他们取消阻止并获取数据,直到没有剩下的数据再重新阻止。
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static BlockingCollection<int> _items = new BlockingCollection<int>();
static void Main(string[] args)
{
//Start up 4 threads
var threads = new Thread[4];
for (int i = 0; i < threads.Length; i++)
{
var iCopy = i;
threads[i] = new Thread(() => ProcessItems(iCopy));
threads[i].IsBackground = true;
threads[i].Start();
}
//Give the threads 5 items to process.
for (int i = 0; i < 5; i++)
{
_items.Add(i);
}
Console.WriteLine("All items queued, sleeping 2 seconds");
Thread.Sleep(2000);
//Give the threads 10 more items to process.
for (int i = 0; i < 10; i++)
{
_items.Add(i);
}
_items.CompleteAdding();
Console.WriteLine("Marked adding complete");
foreach (var t in threads) t.Join();
Console.WriteLine("All threads complete");
Console.ReadLine();
}
static void ProcessItems(int i)
{
var rnd = new Random(i);
foreach (var item in _items.GetConsumingEnumerable())
{
Console.WriteLine("Thread {0} Processing item {1}", i, item);
//Simulate a random amount work
Thread.Sleep(rnd.Next(100, 500));
}
}
}
}
答案 2 :(得分:0)
如果你真的只想释放所有等待的线程,请使用一个信号量数组,每个线程一个。当你想要它们全部去时,在一个循环中向每个信号量发送一个单元。