我试图使我的基础存储库类异步,我遇到了一些麻烦。我在我的C#应用程序中使用Dapper ORM。
基本方法
for(Rect rect : faces.toArray()){
Imgproc.rectangle(frame, rect.tl(), rect.br(), new Scalar(0,0,255),3);
Rect rectCrop = new Rect(rect.x, rect.y , rect.width, rect.height);
Mat imageROI = grayFrame.submat(rectCrop);
//frame is the original mat with the correct size
Imgproc.GaussianBlur(imageROI, frame, new Size(55, 55), 55);
}
通话方法
INSERT INTO temp (input, str, userId)
VALUES (9, 7, 'sure.');
一切都是为了我。我有使用async关键字修饰的方法声明。我在等待异步方法。
我遇到的问题是protected async Task<List<T>> Read<T>(CommandDefinition cmd) {
using(SqlConnection myCon = new SqlConnection(Config.DBConnection)) {
await myCon.OpenAsync();
IEnumerable<T> results = await myCon.QueryAsync<T>(cmd);
List<T> retVal = results.ToList();
myCon.Close();
return retVal;
}
}
上的线程阻塞了。这是我第一次尝试使用async和await,所以我确信我做错了什么,但这并不明显。请帮忙!
答案 0 :(得分:4)
发布的阅读代码很好。问题出在消费代码中。如果您在通话中回复async
或Wait()
或其前一个Result
,请Task
与Task
发生死锁,这很常见链
在这些情况下,一般建议适用:don't block on async code。开始使用async/await
后,您应该在整个调用链中使用async/await
。
因此,您的调用方法变为
public Task<List<Category>> GetAllActiveCategoriesAsync(Guid siteGuid) {
return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);
}
......或
public async Task<List<Category>> GetAllActiveCategoriesAsync(Guid siteGuid) {
List<Category> result = await base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);
// Do something.
return result;
}
答案 1 :(得分:1)
罪魁祸首是:
return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid).Result;
正如Kirill所指出的,只要您在任务中使用.Wait()
或.Result
,就会同步阻止。你需要做的是:
public Task<List<Category>> GetAllActiveCategories(Guid siteGuid) {
return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);
}
这会将一个Task返回给 this 方法的调用方法,依此类推......它必须是异步的&#34;一直向上&#34;。
如果此代码的顶级使用者是ASP.NET,那么你很好。只需返回Task<IActionResult>
(或任务中包含的相应返回类型),框架将为您排序await
。
如果你正在编写一个控制台应用程序,或者无法使其完全异步,那么你必须阻止.Result
或者制作方法async void
并使用await
。遗憾的是,这两个都不是一个很好的解决方案。 Async / await非常具有攻击性,因为你真的必须在整个堆栈中使用它。