理念一
WaitHandle.WaitAny静态方法返回信号等待句柄的索引,因此最简单的解决方案是检查该索引。
例子
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent[] _eventHandles = new[] {new AutoResetEvent(false), new AutoResetEvent(false)};
static void Main()
{
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
var handleIndex = WaitHandle.WaitAny(_eventHandles);
Console.WriteLine(handleIndex == 0 ? "Process1" : "Process2");
}
}
static void Method()
{
if (_random.Next()%2 == 0)
_eventHandles[0].Set();
else
_eventHandles[1].Set();
}
}
想法 2
您还可以使用一个事件句柄和一个 volatile 字段,该字段将指示满足了哪些条件语句,以便在信号后执行适当的过程。
例子
enum Process
{
Process1,
Process2
}
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent _eventHandle = new AutoResetEvent(false);
private static volatile Process _selectedProcess = Process.Process1;
static void Main()
{
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
_eventHandle.WaitOne();
Console.WriteLine(_selectedProcess == Process.Process1 ? "Process1" : "Process2");
}
}
static void Method()
{
_selectedProcess = _random.Next()%2 == 0 ? Process.Process1 : Process.Process2;
_eventHandle.Set();
}
}
想法 3
如果您无法修改外部组件并且您只有事件句柄,那么您可以尝试为每个选项启动新线程并在那里等待相应的信号以执行适当的操作。
例子
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent[] _eventHandles = new[] {new AutoResetEvent(false), new AutoResetEvent(false)};
static void Main()
{
Thread[] processThreads = new Thread[2];
processThreads[0] = new Thread(Process1);
processThreads[0].Start();
processThreads[1] = new Thread(Process2);
processThreads[1].Start();
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
}
}
static void Method()
{
if (_random.Next()%2 == 0)
_eventHandles[0].Set();
else
_eventHandles[1].Set();
}
static void Process1()
{
while (true)
{
_eventHandles[0].WaitOne();
Console.WriteLine("Process1");
}
}
static void Process2()
{
while (true)
{
_eventHandles[1].WaitOne();
Console.WriteLine("Process2");
}
}
}
想法4
如果进程需要少量时间,可以使用ThreadPool.RegisterWaitForSingleObject 方法
例子
static class Program
{
private static Random _random = new Random();
private static AutoResetEvent[] _eventHandles = new[] {new AutoResetEvent(false), new AutoResetEvent(false)};
static void Main()
{
ThreadPool.RegisterWaitForSingleObject(_eventHandles[0], Process1, null, Timeout.Infinite, false);
ThreadPool.RegisterWaitForSingleObject(_eventHandles[1], Process2, null, Timeout.Infinite, false);
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Method);
threads[i].Start();
}
}
static void Method()
{
if (_random.Next()%2 == 0)
_eventHandles[0].Set();
else
_eventHandles[1].Set();
}
static void Process1(object state, bool timedOut)
{
Console.WriteLine("Process1");
}
static void Process2(object state, bool timedOut)
{
Console.WriteLine("Process2");
}
}