AutoResetEvent允许线程通过发信号互相通信。通常,当线程需要独占访问资源时使用该类(AutoResetEvent是操作单个线程的)。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。
如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态。
例子:在上海坐地铁,检票口有个刷卡的通道,一次只能一个人刷卡后通过,而我过后,它又是关闭的,另一个人又得再刷卡.一次操作,只有一个事件,这时就是非终止状态,一般是用来同步访问资源.
Set方法将事件状态设置为终止状态,允许一个或多个等待线程继续;
Reset方法将事件状态设置为非终止状态,导致线程阻止;
WaitOne阻止当前线程,直到当前线程的WaitHandler收到事件信号。
可以通过构造函数的参数值来决定其初始状态,若为true则事件为终止状态从而使线程为非阻塞状态,为false则线程为阻塞状态。
如果某个线程调用WaitOne方法,则当事件状态为终止状态时,该线程会得到信号,继续向下执行。
AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待,也就是说AutoResetEvent一次只唤醒一个线程;
...
public void init() {
isActive = true;
Thread t = new Thread (work);
t.Start ();
}
public void work() {
DownloadMgr mgr = DownloadMgr.getInstance ();
while (mgr.isActive) {
if (!mgr.trigger ()) {
Thread.Sleep (3000);
}
}
}
public bool trigger () {
DownloadFileInfo data = null;
bool empty = true;
lock(syncLock) {
if (list.Count > 0) {
data = list [0];
list.RemoveAt (0);
empty = false;
}
}
if (!empty) {
doDownload (data);
}
return !empty;
}
private void doDownload(DownloadFileInfo data) {
while (_workingCount >= _MaxCount) {
waitHandle.WaitOne();
}
_workingCount++;
OtkClient.DownloadFile (data);
}
public void addDownload(string fileURL, string savePath, DownloadCallback succeedCallback, DownloadCallback failedCallback, LuaFunction progressCallback) {
lock (syncLock) {
DownloadFileInfo info = new DownloadFileInfo ();
info.fileURL = fileURL;
info.realFilePath = savePath;
// 先下载到一个临时文件,然后再复制到正确路径
info.tmpFilePath = savePath + GameController.getInstance().getMilliseconds();
info.succeedCallback = ()=>{
succeedCallback();
onDownloadOver();
};
info.failedCallback = () => {
failedCallback ();
onDownloadOver();
};
info.progressCallback = progressCallback;
list.Add (info);
}
}
private void onDownloadOver() {
_workingCount--;
waitHandle.Set();
}
}
...
网友评论