【发布时间】:2019-02-19 23:11:55
【问题描述】:
我正在尝试做一些与 UI 线程分离的异步 I/O 工作。我在某处读到:
- 1) 对于 CPU 绑定代码,您等待在 使用 Task.Run 方法的后台线程。比如计算素数 数字
- 2) 对于 I/O 绑定代码,您等待返回一个 异步方法中的任务或任务。比如等待 网络或数据库
所以我这样做了:
// in windows form UI
private async void btnImport_Click(object sender, EventArgs e) {
// [...]
List<DataRow> rows = await importer.ImportDataAsync(123, 456);
// [...]
}
// in Importer.ImportDataAsync:
public async Task<List<DataRow>> ImportDataAsync(int parent, int child, CancellationToken token = default(CancellationToken)) {
// [...]
List<DataRow> list = await RealImportFromDB(parent, child);
return list;
// [...]
}
public List<DataRow> RealImportFromDB(int p, int c) {
List<DataRow> rowList;
// here fetch the rows from DB over slow network
// and return the row list
return rowList;
}
使用这种方法会阻止 UI。 如果我像这样调用 RealImportFromDB(...)
List<DataRow> l = await Task.Run(() => RealImportFromDB(parent, child));
UI 未被阻止,但与 IMHO 上方的第 2 点冲突。
我哪里做错了?
最好的问候,亚历克斯
【问题讨论】:
-
您还没有展示如何从数据库中读取数据。如果是同步方法,自然会阻塞。
-
当
RealImportFromDB没有返回Task时,你还等什么?它也应该是async,并且应该等待对数据库的异步方法的调用。使用 async/await 时,它应该从顶部(在您的情况下为按钮单击处理程序)一直到底部(调用数据库)。 -
不确定您是如何遇到运行时错误的,因为它甚至无法编译。您不能等待不返回
Task或Task<T>的方法(等待 RealImportFromDB)。
标签: c# asynchronous async-await task