I am little confuced by the followed situation. If I call SleepBeforeInvoke method, application is suspended on the _task.Wait(); string. But if I call SleepAfterInvoke method, application works fine and control will reach catch clause. Calling the BeginInvoke method works fine as well.
Could anyone explain with maximum details what's the difference between these three methods usage? Why application is suspended if I use SleepBeforeInvoke method, and why it is not if I use SleepAfterInvoke and BeginInvoke methods? Thanks.
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");
    }
}