1.子线程和主线程通信问题
SynchronizationContext的对象不是所有线程都被附加的,只有UI主线程会被附加。
SynchronizationContext对象。这个对像的用处就是可以记录一个(主)线程的上下文然后再子线程处理完之后,要用到主线程去操作的时候可以去Post或者Send一个事件去解决
Send() 是简单的在当前线程上去调用委托来实现(同步调用)。也就是在子线程上直接调用UI线程执行,等UI线程执行完成后子线程才继续执行。
Post() 是在线程池上去调用委托来实现(异步调用)。这是子线程会从线程池中找一个线程去调UI线程,子线程不等待UI线程的完成而直接执行自己下面的代码。
class TestClient {
private Thread workThread;
private SynchronizationContext mainThreadSynContext;
public TestClient()//构造函数当然是主线程执行的
{
mainThreadSynContext = SynchronizationContext.Current; //在这里记录主线程的上下文
workThread = new Thread(new ThreadStart(DoWork));//创建一个新的线程
}
private void OnConnected(object state)//由于是主线程的同步对象Post调用,这个是在主线程中执行 {
//这里就回到了主线程里面了
//做一些事情
}
private void DoWork()//这个是workThread线程执行的
{
//这儿做些事(连接什么的。。。)
//这而干完了
mainThreadSynContext.Post(new SendOrPostCallback(OnConnected), null);//通知主线程
}
}
SynchronizationContext对象。这个对像的用处就是可以记录一个线程的上下文然后再子线程处理完之后,要用到主要程去操作的时候可以去Post或者Send一个事件支解决
WaitHandler:等待所有的线程全部执行完,最后再统计得到的计算结果
WaitHandle[] handlers = new WaitHandle[]{
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false)
};
for (var i = 0; i < handlers.Length; i++)
{
ThreadPool.QueueUserWorkItem(ar =>
{
int index = (int)ar;
Thread.Sleep(1000);
AppCenter.AppendLog("任务:" + index + "开始执行!");
(handlers[index] as AutoResetEvent).Set();
}, i);
}
ThreadPool.QueueUserWorkItem(ar =>
{
WaitHandle.WaitAll(handlers);
AppCenter.AppendLog("所有任务都已经完成了,我不用再等待了。");
});
两个线程的相互通信 :
ManualResetEvent在触发Set()方法会,解除了原有的线程的 WaitOne方法,会一直打印输出。
AutoResetEvent方法时候。每次只会打印一个输出。因为它将 事件的状态设置为终止后,又变为了false.
EventWaitHandle handleA = new AutoResetEvent(false);
EventWaitHandle handleB = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(ar =>
{
AppCenter.AppendLog("A:我是A,我已经开始运行了");
Thread.Sleep(2000);
AppCenter.AppendLog("A:我想睡觉了,B你先跑跑吧。");
EventWaitHandle.SignalAndWait(handleB, handleA);
AppCenter.AppendLog("A:开始工作ing");
Thread.Sleep(3000);
AppCenter.AppendLog("A:这个有点难,问下B");
EventWaitHandle.SignalAndWait(handleB, handleA);
AppCenter.AppendLog("A:不错,今天任务搞定,我也闪人了。");
});
ThreadPool.QueueUserWorkItem(ar =>
{
handleB.WaitOne();
AppCenter.AppendLog("B:我是B,我已经顶替A开始运行了。");
Thread.Sleep(5000);
AppCenter.AppendLog("B:我的事情已经做完了,该让A搞搞了,休息一会。");
EventWaitHandle.SignalAndWait(handleA, handleB);
AppCenter.AppendLog("B:hi,A我搞定了,下班了。");
handleA.Set();
});
Semaphore 控制并行线程的执行
Semaphore sempore = new Semaphore(0, 3);
for (int i = 0; i < 8; i++)
{
ThreadPool.QueueUserWorkItem(ar =>
{
sempore.WaitOne();
AppCenter.AppendLog("\t第:" +((int)ar).ToString() + "个开始运行.");
},i);
}
ThreadPool.QueueUserWorkItem(ar =>
{
for (int i = 0; i < 3; i++)
{
AppCenter.AppendLog("第" + (i + 1).ToString() + "批开始执行.");
sempore.Release(3);
Thread.Sleep(5000);
}
});