【Windows Phone】AutoResetEvent && ManualResetEvent
1. 继承关系 (在System.Threading命名空间中)
AutoResetEvent -> EventWaitHandle -> WaitHandle
ManualResetEvent -> EventWaitHandle -> WaitHandle
2. WaitHandle的属性和方法
2.1 属性
SafeWaitHandle - 安全等待句柄
WaitTimeout - 等待时长
2.2 方法
WaitOne()
WaitOne(System.TimeSpan timeout)
WaitOne(int millisecondsTimeout)
以上三个方法的作用是阻塞当前线程,直到线程收到信号后唤醒。重载的参数是一个时间段,设置了线程阻塞的超时限制,-1为时间无限。
WaitAny(System.Threading.WaitHandle[])
WaitAny(System.Threading.WaitHandle[], System.TimeSpan)
WaitAny(System.Threading.WaitHandle[], int)
以上三个方法的作用是阻塞当前线程,直到线程收到参数中WaitHandle的任一信号后唤醒。
WaitAll(System.Threading.WaitHandle[])
WaitAll(System.Threading.WaitHandle[], System.TimeSpan)
WaitAll(System.Threading.WaitHandle[], int)
以上三个方法的作用是阻塞当前线程,直到线程收到参数中WaitHandle的所有信号后唤醒。
Dispose()
virtual Close()
这两个方法是释放自己句柄相关的所有系统资源。
3. EventWaitHandle
WaitOne() - 阻塞当前线程,返回值表示成功失败
Set() - 设置对应线程状态为唤醒状态,返回值表示成功失败
Reset() - 设置对应线程状态为非唤醒状态,引发线程阻塞,返回值表示成功失败
4. AutoResetEvent和ManualResetEvent的区别
AutoResetEvent正如其名字一样,会自动Reset对应线程的状态;而ManualResetEvent则不会自动重置对应线程的状态。所以在调用Set()操作后,AutoResetEvent在唤醒一个等待线程之后,会重新将状态置为false(阻塞),因此仅会有一个等待线程被唤醒;而ManualResetEvent在调用Set()操作之后,如果不手动重置状态,状态就会保持true(唤醒),所有等待线程都将被唤醒。
5. AutoResetEvent和ManualResetEvent构造bool参数的含义:
true: Initialize status as received signal.
false: Initialize status as non received signal.
6. 实例:
6.1. UI部分
<!--ContentPanel - 在此处放置其他内容--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel Orientation="Vertical"> <ListBox Name="Messages" Height="400"></ListBox> <StackPanel Orientation="Horizontal"> <Button Name="Auto" Content="Auto Start" Click="Auto_Click" Width="230"></Button> <Button Content="Signal" Click="Button_Click" Width="230"></Button> </StackPanel> <StackPanel Orientation="Horizontal"> <Button Name="Manual" Content="Manual Start" Click="Manual_Click" Width="230"></Button> <Button Content="Signal" Click="Button_Click" Width="230"></Button> </StackPanel> </StackPanel> </Grid>
6.2. 实现部分:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Threading; namespace ResetEventTest { public partial class MainPage : PhoneApplicationPage { // Parameter: true - Initialize status as received signal. // false - Initialized status as not received signal. private AutoResetEvent _autoResetEvent = new AutoResetEvent(false); // Parameter: true - Initialize status as received signal. // false - Initialized status as not received signal. private ManualResetEvent _manualResetEvent = new ManualResetEvent(false); private bool _autoReset = true; public MainPage() { InitializeComponent(); } private void Auto_Click(object sender, RoutedEventArgs e) { Messages.Items.Clear(); _autoReset = true; for (int i = 0; i < 4; ++i) { Thread thread = new Thread(new ParameterizedThreadStart(ThreadProc)); thread.Start(i); } } private void Manual_Click(object sender, RoutedEventArgs e) { Messages.Items.Clear(); _autoReset = false; for (int i = 0; i < 4; ++i) { Thread thread = new Thread(new ParameterizedThreadStart(ThreadProc)); thread.Start(i); } } private void ThreadProc(object obj) { int index = (int)obj; if (_autoReset) { _autoResetEvent.WaitOne(); Deployment.Current.Dispatcher.BeginInvoke(() => { Messages.Items.Add(new TextBlock { Text = "Thread " + index + " wake up by auto reset way!" }); }); } else { _manualResetEvent.WaitOne(); Deployment.Current.Dispatcher.BeginInvoke(() => { Messages.Items.Add(new TextBlock { Text = "Thread " + index + " wake up by manual reset way!" }); }); } } private void Button_Click(object sender, RoutedEventArgs e) { if (_autoReset) { _autoResetEvent.Set(); } else { _manualResetEvent.Set(); } } } }
7. 官方实例:http://msdn.microsoft.com/zh-cn/library/system.threading.eventresetmode.aspx