执行异步任务,更改触发事件

时间:2016-10-13 14:32:54

标签: c# wpf asynchronous async-await dispatcher

我有一个异步运行的加载方法。 在这个方法中,我改变了RadioButton的Checked-State。

这很好用,如果我直接执行它或通过Dispatcher.BeginInvoke执行它。

然而,RadioButton有一个“CheckedChanged”-Event。当我打电话

Dispatcher.Invole((Action)()=>{rb.IsChecked=true;}));

我希望我的异步方法可以等待已检查的已更改事件(再次运行异步方法)。

在附加代码中,您将看到执行顺序为:

  1. “的BeginInvoke”
  2. “的EndInvoke”
  3. “RbChanged”
  4. 我想要的是:

    1. “的BeginInvoke”
    2. “RbChanged”
    3. “的EndInvoke”
    4. 这方面有什么选择吗?

      MainWindow.xaml.cs

       public MainWindow()
              {
                  InitializeComponent();
              }
      
              private async enter code herevoid Window_Loaded(object sender, RoutedEventArgs e)
              {
                  await RightAfterLoading();
              }
      
      
              private async Task RightAfterLoading()
              {
                  Debug.WriteLine("BeginInvoke");
                  await Dispatcher.BeginInvoke((Action)(() => { rb.IsChecked = true; }));
                  Debug.WriteLine("EndInvoke");
              }
      
              private async void rb_Checked(object sender, RoutedEventArgs e)
              {
                  await SomethingAfterChecked();
              }
      
              private async Task SomethingAfterChecked()
              {
                  string abc = string.Empty;
                  await Task.Run(() => abc = "RbCheckedChanged");
                  Console.WriteLine(abc);
              }
      

      MainWindow.xaml看起来像:

      <Window x:Class="AsyncAwaitIssue.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:local="clr-namespace:AsyncAwaitIssue"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              Title="MainWindow"
              Width="525"
              Height="350"
              Loaded="Window_Loaded"
              mc:Ignorable="d">
          <Grid>
              <RadioButton x:Name="rb"
                           Checked="rb_Checked"
                           Content="CheckedOrNot"
                           IsChecked="False" />
          </Grid>
      </Window>
      

1 个答案:

答案 0 :(得分:0)

这是async void方法的本质。设置IsChecked时,等待更改事件的事件处理程序执行,但是当您执行该处理程序时,您所做的只是 start 异步操作。处理程序将在这些异步操作完成之前完成。

理想情况下,您应避免出现这种情况。如果您在已更改的事件中执行的工作后需要执行某些操作,那么如果该更改事件将执行该操作,则会更好。如果你不能,你需要在这些代码部分之间手动创建某种形式的通信,并将这些操作紧密地结合在一起。