一般线程问题

loc*_*boy 6 .net c# multithreading

我对C#中的线程很陌生,并且对于那里的内容有几个问题:

  • 在C#中实现线程的方法有哪些?(即我可以想到两个顶部:backgroundWorker,Thread等)

    • 你如何导致死锁,如果有死锁你怎么摆脱它(在C#中)?

    • 后台工作者如何实施?它似乎有一套潜在的方法,但我想知道那些方法和实例是什么......

谢谢!

Rob*_*vey 10

最新的初学者C#中的线程指南在这里:http: //www.albahari.com/threading/

有关完整工作示例的BackgroundWorker文档位于:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

这里解释了死锁:http://www.albahari.com/threading/part2.aspx

线程可以通过多种方式实现.您可以直接使用它们,从ThreadPool中提取它们,或使用任务并行库间接使用它们.


Bri*_*eon 9

在C#中实现线程的方法有哪些?

有各种不同的方式来利用线程; 一些涉及显式创建线程,而另一些则利用已经运行的线程.

你如何导致死锁,如果有死锁你怎么摆脱它(在C#中)?

以下是3种导致死锁的方法.这份清单并非详尽无遗.

从锁定部分调用阻塞方法.

在此示例中,线程A获取一个锁,然后立即调用阻塞方法,同时线程B尝试获取相同的锁,但由于线程A在释放锁之前等待线程B发出信号,因此它被挂起.

public class Example
{
  ManualResetEvent m_Event = new ManualResetEvent(false);

  void ThreadA()
  {
    lock (this)
    {
      m_Event.WaitOne();
    }
  }

  void ThreadB()
  {
    lock (this)
    {
      m_Event.Set();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

无序获取两把锁.

这里不需要解释,因为这是一个众所周知的问题.

public class Example
{
  private object m_LockObjectA = new object();
  private object m_LockObjectB = new Object();

  void ThreadA()
  {
    lock (m_LockObjectA) lock (m_LockObjectB) { }
  }

  void ThreadB()
  {
    lock (m_LockObjectB) lock (m_LockObjectA) { }
  }
}
Run Code Online (Sandbox Code Playgroud)

无锁死锁.

这是我最喜欢的死锁插图,因为没有锁定或阻塞方法.这个问题的微妙之处足以让那些熟悉线程的人感到困惑.这里的问题与缺乏记忆障碍有关.线程A等待线程B设置信号标志,同时线程B等待线程A重置它,同时线程都没有看到对方正在进行的更改,因为编译器,JIT和硬件是自由的以非直观的方式优化标志的读写.

public class Example
{
  private bool m_Signal = false;

  void ThreadA()
  {
    while (!m_Signal);
    m_Signal = false;
  }

  void ThreadB()
  {
    m_Signal = true;
    while (m_Signal);
  }
}
Run Code Online (Sandbox Code Playgroud)

后台工作者如何实施?

这是一个非常简单的逐步程序,可以帮助您入门.

  1. 添加一个事件处理程序,为事件执行实际工作DoWork.
  2. 添加事件处理程序以接收事件的进度信息ProgressChanged.
  3. 添加将在RunWorkerCompleted事件完成时执行的事件处理程序.
  4. RunWorkerAsync从UI线程调用以启动后台操作.这会在DoWork单独的线程上引发事件.
  5. ReportProgress定期从DoWork事件处理程序调用以发布新的进度信息.这会在ProgressChangedUI线程上引发事件.