我很滿意以下情況。如果我調用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