System.Threading.Thread.Sleep(555);
done.Set(); //发送一个信息来调用由RegisterWaitForSingleObject指定的方法
}
public void WaitOrTimer(object state, bool timedOut)
{
RegisteredWaitHandlePacket packet = state as RegisteredWaitHandlePacket;
// bool timedOut –指示是否由于超时而执行到此
if (!timedOut)
{
//如果没有由于超时而执行到此,则取消指定的RegisteredWaitHandle
packet.Handle.Unregister(null);
}
this.Dispatcher.BeginInvoke(() =>
{
txtRegisterWaitForSingleObject.Text +=
String.Format("\r\n是否收到信号: {0}", (!timedOut).ToString());
});
}
}
///用于封装RegisteredWaitHandle类
public class RegisteredWaitHandlePacket
{
public System.Threading.RegisteredWaitHandle Handle { get; set; }
}
}
done.Set(); //发送一个信息来调用由RegisterWaitForSingleObject指定的方法
}
public void WaitOrTimer(object state, bool timedOut)
{
RegisteredWaitHandlePacket packet = state as RegisteredWaitHandlePacket;
// bool timedOut –指示是否由于超时而执行到此
if (!timedOut)
{
//如果没有由于超时而执行到此,则取消指定的RegisteredWaitHandle
packet.Handle.Unregister(null);
}
this.Dispatcher.BeginInvoke(() =>
{
txtRegisterWaitForSingleObject.Text +=
String.Format("\r\n是否收到信号: {0}", (!timedOut).ToString());
});
}
}
///用于封装RegisteredWaitHandle类
public class RegisteredWaitHandlePacket
{
public System.Threading.RegisteredWaitHandle Handle { get; set; }
}
}
对于第一种方法QueueUserWorkItem,我们只要注意两点。首先是参数的定义:
列表12:QueueUserWorkItem方法存在两个重载
QueueUserWorkItem(WaitCallback);
QueueUserWorkItem(WaitCallback, Object);
QueueUserWorkItem(WaitCallback, Object);
在这里,第一个参数用于指定要执行的方法,而第二个参数作为参数传递进方法中。
其次,仅当在线程池中的线程变为可用时才执行上面的方法。如你所想象的,作为线程管理策略的一部分,在线程池创建线程之前总会存在一定程度的延迟。这就是为什么我们调用Thread.Sleep方法的原因。
对于第二种方法RegisterWaitForSingleObject,倒有一些复杂。首先,我们创建了一个AutoResetEvent的实例,传递进一个false参数。然后,我们引进一个辅助类RegisteredWaitHandlePacket来封装另一个RegisteredWaitHandle类。注意,RegisterWaitForSingleObject方法中可以使用多个参数。不过,我们不会再过细地介绍,因为MSDN(http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx)已作出更详细的解释。此外,你也会注意到我们对第二种方法采用了延迟策略。
最后值得注意的是,虽然ThreadPool还提供了两个方法SetMinThreads和SetMaxThreads,但是,在Silverlight中是不可用的,调用它们将会引发异常。有兴趣的读者可以自行试验。
6.小结
在本文中,我们介绍了Silverlight 4编程环境下的五种多线程编程。