我很满意以下情况。如果我调用SleepBeforeInvoke
方法,则应用程序暂挂在_task.Wait();
字符串中。但如果我打电话SleepAfterInvoke
方法,应用程序工作正常,控制将达到catch
条款。调用BeginInvoke
方法也可以。任务取消暂停UI
任何人都可以解释最大的细节这三种方法的用法有什么区别?如果我使用SleepBeforeInvoke
方法,为什么应用程序被暂停,为什么我不使用SleepAfterInvoke
和BeginInvoke
方法?谢谢。
的Win 7,.NET 4.0
XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Name="_textBlock"
Text="MainWindow"></TextBlock>
<Button Grid.Row="1"
Click="ButtonBase_OnClick"></Button>
</Grid>
的.cs:
public partial class MainWindow : Window
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private Task _task;
/// <summary>
/// Application wiil be suspended on string _task.Wait();
/// </summary>
private void SleepBeforeInvoke()
{
for (Int32 count = 0; count < 50; count++)
{
if (_cts.Token.IsCancellationRequested)
_cts.Token.ThrowIfCancellationRequested();
Thread.Sleep(500);
Application.Current.Dispatcher.Invoke(new Action(() => { }));
}
}
/// <summary>
/// Works fine, control will reach the catch
/// </summary>
private void SleepAfterInvoke()
{
for (Int32 count = 0; count < 50; count++)
{
if (_cts.Token.IsCancellationRequested)
_cts.Token.ThrowIfCancellationRequested();
Application.Current.Dispatcher.Invoke(new Action(() => { }));
Thread.Sleep(500);
}
}
/// <summary>
/// Works fine, control will reach the catch
/// </summary>
private void BeginInvoke()
{
for (Int32 count = 0; count < 50; count++)
{
if (_cts.Token.IsCancellationRequested)
_cts.Token.ThrowIfCancellationRequested();
Thread.Sleep(500);
Application.Current.Dispatcher.BeginInvoke(new Action(() => { }));
}
}
public MainWindow()
{
InitializeComponent();
_task = Task.Factory.StartNew(SleepBeforeInvoke, _cts.Token, TaskCreationOptions.None, TaskScheduler.Default);
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
try
{
_cts.Cancel();
_task.Wait();
}
catch (AggregateException)
{
}
Debug.WriteLine("Task has been cancelled");
}
}
任务异步应该取代您对线程的需求。除非你知道你在做什么,否则坚持单线程异步。另请阅读Stephen Cleary的异步博客。 – Aron 2014-09-11 06:51:30
@Aron,.net 4.0 :(没有异步等待 – monstr 2014-09-11 06:59:54
我会建议在这种情况下使用Rx.Net或升级...严重...它的价值升级...如果只是因为'任务'被打破。 net 4.0,不要使用它''Task.ContinueWith'#$%* s你的'SynchronizationContext.Current',并且基本上破坏了WinForms和WPF – Aron 2014-09-11 07:00:47