我试图了解 Task.Run Wait() 异步等待是如何工作的。
我已经阅读了这个页面:了解在一行中使用Task.Run Wait()异步等待的使用,但不太理解它。
在我的代码中,我从Microsoft EventHub接收事件,并使用实现IEventProcessor
的类处理它们。我在 ConvertToEntity
() 中调用 DoOtherWork()
方法,这是一个异步方法,这是一个同步
方法。由于该方法是异步
的,因此我使用 Task.Run()
和异步
来委派。(即 Task.Run(async () =
我的问题是:
*两者之间有什么区别
*哪种代码是合适的和/或安全的(=不会导致死锁)
*在什么情况下会导致僵局
*为什么任务。Run()
解决我遇到的死锁?(详见下文)
注:我在用。网芯3.1。
我为什么使用任务。Run()
或< code >。Wait()(该方法是在NET Core Web API方法中调用的,死锁大多发生在我们运行执行该方法的单元测试时),所以我们使用了< code>Task。Run(async () =
当我们使用< code>AbcAsync()时,我的团队出现了几次死锁问题。结果
public class EventProcessor : IEventProcessor
{
public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
...
var result = await eventHandler.ProcessAsync(messages);
...
}
}
public Task async ProcessAsync(IEnumerable<EventData> messages)
{
...
var entities = ConvertToEntity(messages);
...
}
public List<Entity> ConvertToEntity(IEnumerable<EventData> messages)
{
var serializedMessages = Serialize(messages);
var entities = autoMapper.Map<Entity[]>(serializedMessages);
// Task.Run(async () => entities = await DoAnotherWork(entities)).Wait(); // before change
entities = DoAnotherWork(entities).Result; // after change
return entities;
}
public Task async Entity[] DoAnotherWork(Entity[] entities)
{
// Do stuff async
await DoMoreStuff(entities)...
}
两者之间有什么区别?
Task.Run
开始在线程池线程上运行委托;直接调用该方法将开始在当前线程上运行委托。
学习async
时,将所有内容都分开,这样您就可以准确地看到发生了什么:
entities = DoAnotherWork(entities).Result;
相当于:
var entitiesTask = DoAnotherWork(entities);
entities = entitiesTask.Result;
和这个代码:
Task.Run(async () => entities = await DoAnotherWork(entities)).Wait();
相当于:
async Task LambdaAsMethod()
{
entities = await DoAnotherWork(entities);
}
var runTask = Task.Run(LambdaAsMethod);
runTask.Wait();
哪种代码是合适的和/或安全的(=不会导致死锁)?
应避免在 ASP.NET 环境中使用 Task.Run
,因为它会干扰线程池的 ASP.NET 处理,并在不需要线程池时强制线程切换。
如果是,在什么情况下会导致死锁?
常见的死锁场景需要两件事:
awaid
最好的解决方案是删除第一个条件;换句话说,一路使用“async
”。要在这里应用它,最好的解决方案是完全删除阻塞:
public Task async ProcessAsync(IEnumerable<EventData> messages)
{
...
var entities = await ConvertToEntityAsync(messages);
...
}
public async Task<List<Entity>> ConvertToEntityAsync(IEnumerable<EventData> messages)
{
var serializedMessages = Serialize(messages);
var entities = autoMapper.Map<Entity[]>(serializedMessages);
entities = await DoAnotherWork(entities);
return entities;
}
为什么任务。Run()解决我遇到的死锁?(详见下文)
.NET Core 根本没有“上下文”,因此它使用线程池上下文。由于 .NET Core 没有上下文,因此它会删除死锁的第二个条件,并且不会发生死锁。如果您在 ASP.NET Core 项目中运行它。
我的团队在使用AbcAsync()时多次出现死锁问题。Result或.Wait()(该方法是在NET Core Web API方法中调用的,死锁主要发生在我们运行执行该方法的单元测试时)
一些单元测试框架确实提供了上下文——最明显的是xUnit。xUnit提供的上下文是同步上下文,因此它的行为更像UI上下文或ASP.NET前核心上下文。因此,当您的代码在单元测试中运行时,它确实具有死锁的第二个条件,死锁可能会发生。
如上所述,最佳解决方案是完全去除堵塞;这将有助于提高服务器的效率。但是如果必须完成阻塞,那么您应该将单元测试代码包装在<code>Task中。运行,而不是ASP。NET核心代码。
我只想确保我很好地理解异步await和task.run或task.whenall之间的区别 所以异步等待就是处理异步方法。它意味着隐含着一个处理顺序。 我在不阻塞主线程的情况下运行了一个很长的处理,并等待结果继续。 对于task.run和task.when,这里有一个多线程的新概念。这意味着我可以在一个新线程上启动一个长进程,它不会等待完成来继续代码。代码在新线程上。在这个线程上,我可以等待方法。
我在网上搜索了很多关于vs await async,但是在这个特定的使用场景中,我并不真正理解其中的区别。我相信情况很简单。 vs. 其中,是一个异步方法,其中包含一些异步调用,例如使用wait调用db。 问题: 在这种情况下,两者之间有什么区别吗?任何帮助或意见,谢谢!
我们有一个async/await方法,它通过实体框架调用存储的过程,该框架由同步方法调用。 需要很长的时间来执行,这可能就是我们编写async/await的原因,它可以被多个地方使用。 我知道我们不应该混合异步和同步调用,但假设我们有这种情况并且我们正在使用 从同步方法 调用异步方法 GetLoanDataAsync,我理解该方法 - 将在后台线程上运行。 我的问题是,如果我们有一个异步方法< c
使用asyn/wait vs wait有什么区别task.run() 等待任务。运行示例- 异步等待示例-
我一直试图理解C#中的Async/await和Task,但尽管看了youtube视频,阅读了文档,并参加了pluralsight课程,但一直失败得很厉害。 我希望有人能帮助回答这些稍微抽象的问题,帮助我的大脑摆脱困境。 1.为什么说async/await启用了一个“Asynchonrous”方法,而async关键字本身什么也不做,而await关键字添加了一个挂起点?添加挂起点不是强制方法同步操作,
问题内容: 我想同时下载一些文件,例如100个文件。因此,我决定将下载线程添加到调度队列中,GCD会调整同时运行多少个线程。 这里的问题是:中的块将立即完成,因为它将在另一个线程上运行。因此,如果长度为100,它将立即创建100个线程。 如何配置块以等待下载任务完成?我不想使用,因为它只允许同时运行一个下载任务。 问题答案: 要扩展Abhinav的答案,您应该: 使用创建一个组。 在开始每个下载任