nan*_*nan 6 c# events multithreading
我想在两个线程之间实现以下通信:
线程Alpha执行某些操作,然后暂停.接下来第二个线程(Beta)引发并恢复Alpha线程的事件.这个循环继续......
我做了类似下面的事情,但我不确定它是否是一个合适的设计.我也注意到Thread.Suspend()
并且Thread.Resume()
已被弃用.我期待听到有关此实现的任何建议以及更换弃用方法的首选方法.
namespace ThreadTester
{
delegate void ActionHandler();
class Alpha
{
internal Thread alphaThread;
internal void Start()
{
while (true)
{
this.alphaThread.Suspend();
Console.WriteLine("Alpha");
}
}
internal void Resume()
{
while (this.alphaThread.ThreadState == ThreadState.Suspended)
this.alphaThread.Resume();
}
}
class Beta
{
internal event ActionHandler OnEvent;
internal void Start()
{
for (int i = 0; i < 15; i++)
{
OnEvent();
Thread.Sleep(1000);
}
}
}
class Program
{
static void Main(string[] args)
{
Alpha alpha = new Alpha();
alpha.alphaThread = new Thread(new ThreadStart(alpha.Start));
alpha.alphaThread.Start();
while (!alpha.alphaThread.IsAlive) ;
Beta beta = new Beta();
beta.OnEvent += new ActionHandler(alpha.Resume);
Thread betaThread = new Thread(new ThreadStart(beta.Start));
betaThread.Start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Jor*_*ren 12
这是您通常使用等待句柄的地方,特别是事件等待句柄.
如果WaitOne
在等待句柄上调用该方法,它将阻塞您的线程,直到某个其他线程调用Set
同一个等待句柄.
事件等待句柄有两个重要的简单类型:AutoResetEvent将在线程通过后自动重置WaitOne
.只有在调用时,ManualResetEvent才会自动重置Reset
.
Dan*_*ant 10
这是一个常见的同步问题,有几种方法(如果你不是非常小心的话,所有这些方法都很容易搞砸):
等待处理(Joren已经描述了这些).
Monitor.Wait和Monitor.Pulse.这里有一个问题是Pulse只会唤醒已经处于Wait状态的线程,所以你必须小心如何管理同步对象的锁定.
使用.NET 4中的新TPL(也可以反向移植到.NET 3.5),您可以设置异步任务并根据以前完成的任务定义任务继续的条件.理解如何构建代码以利用任务和延续有一点学习曲线,但它比通过简单使用低级同步结构的非常艰难的道路要好得多(从长远来看). .这也为您提供了一个很好的前进道路,可以为您的逻辑添加更强大的错误处理和取消支持,因为协调这些内容的细节已经融入到TPL中.
您的代码具有生产者 - 消费者模式的"感觉",但以错误的方式实现.你肯定不希望使用Thread.Suspend
,并Thread.Resume
以这种方式(或实际的任何方式).通过BlockingCollection
类实现规范的生产者 - 消费者模式,实际上很容易获得您想要的排序和信号.
public class ProducerConsumer
{
private BlockingCollection<object> m_Queue = new BlockingCollection<object>();
public ProducerConsumer()
{
new Thread(Producer).Start();
new Thread(Consumer).Start();
}
private void Consumer()
{
while (true)
{
object item = m_Queue.Take(); // blocks when the queue is empty
Console.WriteLine("Consumer");
}
}
private void Producer()
{
while (true)
{
m_Queue.Add(new object());
Thread.Sleep(1000);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中Consumer
,Producer
将分别相当于你alphaThread
和betaThread
.
归档时间: |
|
查看次数: |
8377 次 |
最近记录: |