在WPF应用程序中使用wait

本文关键字:wait WPF 应用程序 | 更新日期: 2023-09-27 18:19:49

我正在尝试在c#中执行异步函数。我可以用这个代码得到它:

private async Task loadData()
{
     try
     {
         await Task.Run(() => { testTableAdapter.Fill(testDataSet.tbl); });
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.ToString());
     }
}

但由于我试图访问UI控件,我尝试在不执行Task.Run的情况下进行访问(这样我就不会启动新的工作线程),但我遇到了一个我不理解或不知道如何修复的错误。

private async Task loadData()
{
     try
     {
          await  testTableAdapter.Fill(testDataSet.tbl); 
          perComboBox.text = loadedSearch.toString();
     }
     catch (Exception ex)
     {
          MessageBox.Show(ex.ToString());
     }
}

错误为:

严重性代码描述项目文件行错误CS1061"int"do不包含"GetAwaiter"的定义,也没有扩展方法找不到接受"int"类型的第一个参数的"GetAwaiter"(您是否缺少使用指令或程序集引用?)

在WPF应用程序中使用wait

这是您的解决方案。请阅读更多Stephen Cleary主页提供的内容。线程和后台工作程序在使用异步时已过时。根据您使用LoadData的位置,提供一个同步方法总是一个好主意。然后,您可以根据实现情况将它包装成异步的。你真的应该从一个合适的DataAccessLayer返回TableAdaper结果。记住关注点的分离。

将您的方法更改为:

private int LoadData()
{
    try
    {
        return testTableAdapter.Fill(testDataSet.tbl); 
    }
    catch (Exception ex)
    {
         MessageBox.Show(ex.ToString());
    }
    return -1;
}

现在是调用类中的异步包装器。实际上,异步部分应该在窗口加载或其他GUI事件中。下面是一个按钮点击的例子,它将填充您的数据。.ConfigureAwait(false)表示awaiter将被发送到调度器,而不是在GUI线程上执行。还可以考虑将MVVM用于WPF。我想注意的是,如果调用Window_Closing事件,_cToken的CancellationTokenSource将被设置为Cancel()。这是为了确保您的异步操作得到清理。

private async void _btnTruck_OnClick(object sender, RoutedEventArgs e)
{
    int count = 0;
    try
    {
        count = await Task.Run(() => LoadData(), _cToken).ConfigureAwait(false);
        perComboBox.text = loadedSearch.toString();
    }
    catch (Exception ex)
    {
        _log.Error(ex); 
    }
}