如何从MainWindow调用异步方法?

use*_*753 1 c# wpf xaml async-await

所以我写了一个快速的async方法来DataTable从Oracle数据库中获取一些数据.我怎么想在MainWindow()不阻止UI线程的情况下调用它?在async/ wait模型并没有真正太大的意义存在.

    async Task<DataTable> AccessOracleAsync()
    {
        DataTable dt;
        using(OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings["connStr"].ConnectionString))
        using (OracleCommand cmd = new OracleCommand(@"SELECT * FROM myTbl", conn))
        {
            await conn.OpenAsync();
            using (var reader = await cmd.ExecuteReaderAsync())
            {
                dt = new DataTable();
                dt.Load(reader);                        
            }

        }
        return dt;
    }
Run Code Online (Sandbox Code Playgroud)

Pet*_*iho 9

在没有看到你的构造函数的情况下,很难说那些可能"有意义"的东西.但是你在这里至少有几个选择.

选项#1:将调用放入构造函数中.

在这种情况下,您无法创建该方法async,并且您肯定不希望继续执行在构造函数返回之前需要执行的任何操作.但是你仍然可以有效地完成C#在一个async方法中为你做的事情:

public MainWindow()
{
    InitializeComponent();

    AccessOracleAsync().ContinueWith(task => { /* do some other stuff */ },
        TaskScheduler.FromCurrentSynchronizationContext());
}
Run Code Online (Sandbox Code Playgroud)

这将在UI线程上执行延续,就像你写的一样await AccessOracleAsync(); /* do some other stuff */.必要时在continuation方法中添加异常处理(即检查task对象和句柄).

选项#2:将呼叫置于其他地方.

有人建议您使用该Loaded事件,您可以这样做.这可能看起来像这样:

private async void Window_Loaded(object sender, RoutedEventArgs e)
{
    await AccessOracleAsync();

    // do some other stuff
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果后者看起来合适,恕我直言.它允许C#编译器为您做繁重的工作,包括处理异常(您可以将调用包装在try/中,catch并且所有内容都"正常").