这是我对async / await的实现,但我不确定我是否正确执行。
代码按预期工作,但我希望有人查看这些小代码来指出任何错误。
public class DbUtils
{
public static List<string> GetDataSources()
{
//I have removed some logic from here as it's not important to my question
List<string> names = new List<string>();
names = SomeClass.SomeLongSystemMethod();
return names;
}
public static async Task<List<string>> GetDataSourcesAsync()
{
//This is a place where I have my doubts
return await Task.Run(() =>
{
return GetDataSources();
});
}
}
public class SomeOtherClass
{
private async void BT_RefreshServerName_Click(object sender, EventArgs e)
{
CB_ServerName.DataSource = await DbUtils.GetDataSourcesAsync();
}
}
编辑:
我的新版代码看起来像这样。
public class SomeOtherClass
{
private async void BT_RefreshServerName_Click(object sender, EventArgs e)
{
try
{
BT_RefreshServerName.Enabled = false;
//.ConfigureAwait(true) (this is a default) is to attempt to
//marshal the continuation back to the original context as the
//result is used to update UI.
CB_ServerName.DataSource = await Task.Run(
() => DbUtils.GetDataSources()).ConfigureAwait(true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK);
}
finally
{
BT_RefreshServerName.Enabled = true;
}
}
}
}
public class DbUtils
{
public static List<string> GetDataSources()
{
//Some logic
List<string> names = new List<string>();
names = SomeClass.SomeLongSystemMethod();
return names;
}
}
答案 0 :(得分:4)
GetDataSourcesAsync
的实现被称为“async over sync”,并且通常被认为是反模式(虽然公平地说,它没有“同步过度那么糟糕”异步“)。它至少会起作用,但是如果你实际上没有真正的async
操作,那么使用工作线程(通常是线程池),后面跟{实际上没有任何区别{1}} / Invoke
返回UI线程(进行UI更新)。
如果这是问题,它会起作用。
现在,如果BeginInvoke
实际使用了GetDataSourcesAsync
数据访问方法; 然后这将是伟大的代码。在那个事件中你不需要*Async
,顺便说一句。
另外:在事件处理程序中添加一些异常处理。