Max*_*sky 167 c# multithreading
我以前从未在C#中使用线程,我需要有两个线程,以及主UI线程.基本上,我有以下几点.
public void StartTheActions()
{
//Starting thread 1....
Thread t1 = new Thread(new ThreadStart(action1));
t1.Start();
// Now, I want for the main thread (which is calling `StartTheActions` method)
// to wait for `t1` to finish. I've created an event in `action1` for this.
// The I wish `t2` to start...
Thread t2 = new Thread(new ThreadStart(action2));
t2.Start();
}
Run Code Online (Sandbox Code Playgroud)
所以,基本上,我的问题是如何让一个线程等待另一个线程完成.做这个的最好方式是什么?
Chr*_*s S 259
我可以看到5个选项:
和米奇的回答一样.但这会阻止你的UI线程,但是你会为你内置一个Timeout.
WaitHandleManualResetEvent是WaitHandlejrista建议的.
需要注意的一件事是,如果你想等待多个线程,WaitHandle.WaitAll()默认情况下不会工作,因为它需要一个MTA线程.您可以通过标记您的Main()方法来解决这个问题MTAThread- 但这会阻止您的消息泵,并且不建议从我读过的内容.
见这个页面乔恩斯基特有关事件和多线程,它可能是一个事件能够成为之间unsubcribed if和EventName(this,EventArgs.Empty)-它之前发生在我身上.
(希望这些编译,我还没试过)
public class Form1 : Form
{
int _count;
void ButtonClick(object sender, EventArgs e)
{
ThreadWorker worker = new ThreadWorker();
worker.ThreadDone += HandleThreadDone;
Thread thread1 = new Thread(worker.Run);
thread1.Start();
_count = 1;
}
void HandleThreadDone(object sender, EventArgs e)
{
// You should get the idea this is just an example
if (_count == 1)
{
ThreadWorker worker = new ThreadWorker();
worker.ThreadDone += HandleThreadDone;
Thread thread2 = new Thread(worker.Run);
thread2.Start();
_count++;
}
}
class ThreadWorker
{
public event EventHandler ThreadDone;
public void Run()
{
// Do a task
if (ThreadDone != null)
ThreadDone(this, EventArgs.Empty);
}
}
}
Run Code Online (Sandbox Code Playgroud)
public class Form1 : Form
{
int _count;
void ButtonClick(object sender, EventArgs e)
{
ThreadWorker worker = new ThreadWorker();
Thread thread1 = new Thread(worker.Run);
thread1.Start(HandleThreadDone);
_count = 1;
}
void HandleThreadDone()
{
// As before - just a simple example
if (_count == 1)
{
ThreadWorker worker = new ThreadWorker();
Thread thread2 = new Thread(worker.Run);
thread2.Start(HandleThreadDone);
_count++;
}
}
class ThreadWorker
{
// Switch to your favourite Action<T> or Func<T>
public void Run(object state)
{
// Do a task
Action completeAction = (Action)state;
completeAction.Invoke();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你确实使用了_count方法,那么使用它来增加它可能是一个想法(为了安全起见)
Interlocked.Increment(ref _count)
我有兴趣知道使用委托和事件进行线程通知之间的区别,我知道的唯一区别是事件被同步调用.
这个问题的答案用这种方法非常清楚地描述了你的选择.
事件/委托的处理方式意味着您的事件处理程序方法在thread1/thread2上而不是主UI线程,因此您需要在HandleThreadDone方法的顶部切换回来:
// Delegate example
if (InvokeRequired)
{
Invoke(new Action(HandleThreadDone));
return;
}
Run Code Online (Sandbox Code Playgroud)
Mit*_*eat 56
加
t1.Join(); // Wait until thread t1 finishes
Run Code Online (Sandbox Code Playgroud)
在你启动它之后,但这不会有太大的成就,因为它与在主线程上运行的结果相同!
如果你想了解.NET中的线程,我强烈建议阅读Joe Albahari 在C#免费电子书中的线程.
jri*_*sta 32
前两个答案很棒,适用于简单的场景.但是,还有其他方法可以同步线程.以下内容也适用:
public void StartTheActions()
{
ManualResetEvent syncEvent = new ManualResetEvent(false);
Thread t1 = new Thread(
() =>
{
// Do some work...
syncEvent.Set();
}
);
t1.Start();
Thread t2 = new Thread(
() =>
{
syncEvent.WaitOne();
// Do some work...
}
);
t2.Start();
}
Run Code Online (Sandbox Code Playgroud)
ManualResetEvent是.NET框架必须提供的各种WaitHandle之一.它们可以提供比简单但非常常见的工具(如lock()/ Monitor,Thread.Join等)更丰富的线程同步功能.它们还可以用于同步两个以上的线程,允许复杂的场景,如"主"线程协调多个"子"线程,多个并发进程依赖于彼此的几个阶段进行同步等.
Say*_*emi 24
如果从.NET 4使用,此示例可以帮助您:
class Program
{
static void Main(string[] args)
{
Task task1 = Task.Factory.StartNew(() => doStuff());
Task task2 = Task.Factory.StartNew(() => doStuff());
Task task3 = Task.Factory.StartNew(() => doStuff());
Task.WaitAll(task1, task2, task3);
Console.WriteLine("All threads complete");
}
static void doStuff()
{
//do stuff here
}
}
Run Code Online (Sandbox Code Playgroud)
来自:https://stackoverflow.com/a/4190969/1676736