如何从MainWindow调用异步方法? [英] How to call async method from MainWindow?
问题描述
因此,我编写了一个快速的async
方法,以将一些数据从Oracle数据库获取到DataTable
中.我应该如何在不阻止UI线程的情况下从MainWindow()
调用它? async
/wait
模型在那里真的没有多大意义.
So I wrote a quick async
method to get some data into a DataTable
from an Oracle db. How am I suppose to call this from MainWindow()
without blocking UI thread? The async
/wait
model doesn't really make much sense there.
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;
}
推荐答案
在没有看到您的构造函数的情况下,很难说出那里的意义".但是您这里至少有两个选择.
Without seeing your constructor, it's hard to say what might "make sense" there. But you have at least a couple of options here.
选项1::将调用放入构造函数中.
Option #1: put the call in the constructor.
在这种情况下,您将无法使用方法async
,并且最肯定地是您不希望继续执行构造函数返回之前需要做的任何事情.但是您仍然可以通过async
方法有效地完成C#为您所做的事情:
In this case, you can't make the method async
, and you most certainly don't want your continuation to do anything that needs to be done before the constructor returns. But you can still do effectively what C# would have done for you in an async
method:
public MainWindow()
{
InitializeComponent();
AccessOracleAsync().ContinueWith(task => { /* do some other stuff */ },
TaskScheduler.FromCurrentSynchronizationContext());
}
这将在UI线程上执行延续,就像您已经编写了await AccessOracleAsync(); /* do some other stuff */
一样.必要时在延续方法中添加异常处理(即检查task
对象并进行适当处理).
That will execute the continuation on the UI thread, as if you had written await AccessOracleAsync(); /* do some other stuff */
. Add exception handling in the continuation method as necessary (i.e. inspect the task
object and handle appropriately).
选项2::将通话转移到其他地方.
Option #2: put the call somewhere else.
建议使用Loaded
事件,您可以执行此操作.可能看起来像这样:
It has been suggested to use the Loaded
event, which you can do. That might look something like this:
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await AccessOracleAsync();
// do some other stuff
}
请注意,如果后者似乎合适,恕我直言是可取的.它使C#编译器可以为您完成繁重的工作,包括处理异常(您可以将调用包装在try
/catch
中,并且所有内容都可以使用).
Note that if the latter seems appropriate, IMHO it's preferable. It lets the C# compiler do the heavy-lifting for you, including dealing with exceptions (you can just wrap the call in try
/catch
and everything "just works").
这篇关于如何从MainWindow调用异步方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!