本问题已经有最佳答案,请猛点这里访问。

在浏览了许多文章和视频后,我仍然对异步编程有疑问。我正在一个项目中,在服务层中,我已将所有方法创建为异步方法。所有返回Task < T >或Task(我确保不返回void)。

现在到问题。我的Api调用异步方法,该方法在内部调用其他异步方法,甚至可能调用其他异步方法。因此,每次遇到异步方法时,我都在等待。

我认为,这种方法的缺点是,由于我每次等待异步时都在等待结果,这将花费很多时间。例如:

public async Task DoMainTask(int ActionId, int ItemId, int UserId)

{

await DoTask1(ActionId,ItemId,UserId);  3 sec

await DoTask2(ActionId,ItemId,UserId);  3 sec

await DoTask3(ActionId,ItemId,UserId);  3 sec

}

因此,我不想等待9秒钟,因为这里的所有任务都是相互独立的。

我想做类似的事情:

public async Task DoMainTask(int ActionId, int ItemId, int UserId)

{

List lst = new List();

t1= DoTask1(ActionId,ItemId,UserId);

lst.Add(t1);

t2 = DoTask2(ActionId,ItemId,UserId);

lst.Add(t2);

t3 = DoTask3(ActionId,ItemId,UserId);

lst.Add(t3);

await Task.WhenAll(lst);

// do some work

return xyz;

}

这大概需要5-6秒。我该怎么做呢?

每当我尝试使用第二种方法时,都会出错:

在先前的异步操作完成之前,第二个操作在此上下文上开始

DoTask1定义为:

public async Task DoTask1 (int ActionId, int ItemId, int UserId)

{

try

{

DailyActivityPoint dailyActivityPoint = new DailyActivityPoint()

{

ActionId = ActionId,

CreatedDate = DateTime.Now,

ItemId = ItemId,

UserId = UserId,

PointsAccumulated = await GetPointsAwardedForAction(ActionId)

};

_entities.DailyActivityPoints.Add(dailyActivityPoint);

await _entities.SaveChangesAsync();

}

catch (Exception ex)

{

}

}

在DoTask1内部,我还调用了异步方法。

怎么做以及最佳实践是什么?

将async / await用于I / O之类的不受CPU约束的东西,而将线程用于诸如更大/更长的计算之类的与CPU约束的东西。

我现在无法启动Visual Studio来帮助您,但是绝对要在Task.WhenAll前面等待

我做到了忘了放在这里:p修改帖子。

另外,您在什么环境中运行它?标准桌面.NET?我认为pmichaels.net/tag/可能描述了您的问题-您使用的是EF吗?

您的问题是您不能在多个任务中重用实体框架。您将需要为每个任务创建一个新的dbcontext。见stackoverflow.com/questions/36036401/

是。我正在使用EF进行WebAPI2项目。您共享的文章中提供的解决方案是针对用户使用IOC的问题的解决方案。我不是。至少在此模块中没有。没有为DbContext创建界面,仅针对我创建的服务。尽管我已经在属于同一项目的不同模块中使用了autofac,但是不要认为它将以任何方式影响它。我是否需要以异步Task < T >的Task < T >形式创建子方法。

我相信您会遇到此处所述的线程安全问题。如果是这样,您需要确保对于每个进入EF的"等待",它都使用自己的DbContext实例。

因此,请确保您未使用DbContext单例。实例化一个新实例,如果可以的话,或像他在链接中那样使用一个容器来棘手(容器是您的朋友)

啊,塞拉德安全...好。 谢谢您的帮助。 我会尽量记住这些事情:)

从您的代码段中猜测,您的_entities似乎直接是您的DbContext,因此可能就像单身汉一样。 如果您在函数内创建并销毁本地_entities,则可能会成功。

是的,它成功了。 在方法内部创建上下文,而不是使用共享上下文,并且效果很好...谢谢:)

很高兴为您提供帮助!

也许您应该在编写异步方法时使用此指南

指导方针:

用编写常规方法的普通方法编写方法,然后将其转换为异步方法。

在方法声明中使用async关键字。

public async Task ExampleMethodAsync()

{

// . . . .

}

在调用异步进程/方法的代码中使用await关键字。

int resultValue = await ExampleMethodAsync();

注意:await只能在由async关键字修改的async方法中使用。

在async方法中使用正确的返回类型之一以获取结果

return types for an async method need to be one of the following:

如果您的方法具有一个返回语句,其中操作数的类型为TResult,则执行任务。

如果您的方法没有return语句或没有操作数的return语句,则执行任务。

如果您正在编写异步事件处理程序,则为void。

在调用方法名称的末尾添加"异步"后缀。这不是必需的,但可以考虑

在C#中编写异步方法的约定。

public async Task ExampleCallingMethodAsync()

{

// . . . .

}

在异步方法代码中至少包含一个await表达式。

在await表达式中暂停async方法不会

构成该方法的出口,最后块不运行。

public async Task ExampleMethodAsync()

{

//some code

string pageContents = await client.GetStringAsync(uri);

//some more code

return pageContents.Length;

}

注意:

您必须调整异步方法返回的内容。返回的对象必须与异步方法的类型Task< T >相匹配

如果异步方法未使用await运算符标记悬浮点,则该方法

尽管使用了async修饰符,但仍像同步方法一样执行。编译器发出一个

警告此类方法。

下面是将典型方法转换为异步方法的方法

private void WebPage(string someURI)

{

WebClient webClient = new WebClient();

string pageContent = webClient.DownloadString(someURI);

Console.WriteLine(pageContent);

}

变成:

private async void WebPageAsync(string someURI)

{

WebClient webClient = new WebClient();

string pageContent = await webClient.DownloadStringTaskAsync(someURI);

Console.WriteLine(pageContent);

}

我希望这可以帮到你?

感谢您的帖子,尽管我已经知道了很多。 :)

c# task添加顺序_关于c#:Task和async等待所需的指导相关推荐

  1. C# Task 循环任务_理解C#中的ValueTask

    英文:devblogs.microsoft.com 译文:cnblogs.com/xiaoxiaotank/p/13206569.html 译者:xiaoxiaotank 前言 Task类是在.NET ...

  2. ansible playbook play task执行顺序

    当我们使用ansible-playbook执行playbook,我们可以指定一个或者多个playbook,而一个playbook中可以有多个play,这些play下面又会存在一个或者多个task,这些 ...

  3. 的run代码_小心使用 Task.Run 续篇

    关于前两天发布的文章:为什么要小心使用 Task.Run,对文中演示的示例到底会不会导致内存泄露,给很多人带来了疑惑.这点我必须向大家道歉,是我对导致内存泄漏的原因没描述和解释清楚,也没用实际的示例证 ...

  4. .NET 中 如果一个Task A正在await另一个Task B,那么Task A是什么状态

    .NET 中 如果一个Task A正在await另一个Task B,那么Task A是什么状态?答案是:WaitingForActivation 新建一个.NET Core控制台程序,输入如下代码: ...

  5. unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect

    unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect<7/10/2017> 1.因为要实现声音的交互,首先你得给目标对象添加一个B ...

  6. 可执行文件添加快捷方式_如何停止Windows向快捷方式文件名添加“-快捷方式”...

    可执行文件添加快捷方式 When you make a new shortcut in Windows, it automatically adds "- Shortcut" to ...

  7. java 异步调用 事务_深入理解Spring注解@Async解决异步调用问题

    序言:Spring中@Async 根据Spring的文档说明,默认采用的是单线程的模式的.所以在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的. 那么当多个任务的执行势必会相互影响. ...

  8. [Windows Phone] 为应用添加后台计划任务 – Scheduled Task Agent

    前段时间做过一个天气应用,一直是只支持前台获取数据,上周末参加了Windows Phone的CodeJam和高手们交流了一下,发现实现后台定时更新功能也不是很难,于是在网上找一些资料,在找资料的过程中 ...

  9. C# Task 循环任务_聊聊 JavaScript 的并发、异步和事件循环

    本文作者:Cody Chan,题图来自 Jake Archibald JavaScript 作为天生的单线程语言,社区经常聊 JavaScript 就聊异步.聊 Event Loop,看起来它们好像难 ...

最新文章

  1. Go 学习笔记(49)— Go 标准库之 io/ioutil(读写文件、获取目录下的文件和子目录、创建临时目录和文件)
  2. Nature:如何做一篇肠道菌群免疫的顶级文章
  3. android-async-http使用例子
  4. 0寄存器与arm_如何在ARM下进行高效的C编程?
  5. dw按钮图片滚动js_使用 React Hooks 实现仿石墨的图片预览插件(巨详细)
  6. 零基础学编程学java还是python-小白学编程选java、php、前端还是python
  7. AI:Algorithmia《2021 enterprise trends in machine learning 2021年机器学习的企业趋势》翻译与解读
  8. 趣学python3(10)-函数注释方法
  9. NSUserDefaults的用法(轻量级本地数据存储)
  10. MyBatis的association示例
  11. JavaScript高级程序设计学习笔记第二十章--JSON
  12. 2.2_ 4_ FCFS、SJF、 HRRN调度算法
  13. ros中move_group的参数动态设置
  14. 【Maven】mvn install 本地jar 或者 项目 添加到maven仓库中
  15. JavaScript的浪漫,520一生一世!!
  16. Windows 端口
  17. 大学生html电影网页设计作业成品 我喜欢的电影榜单题材网页制作代码 简单静态网页模板下载
  18. 子图数正方形和长方形数量
  19. 别做老好人,你的善良应该带点锋芒
  20. 计算机网络实验水晶头,计算机网络 实验1 双绞线水晶头制作.docx

热门文章

  1. linux加protobuf变量环境,protobuf简单介绍和ubuntu 16.04环境下安装教程
  2. oracle产生随机日期,Oracle生成随机日期时间
  3. spring框架做全局异常捕获_springboot springmvc抛出全局异常的解决方法
  4. dw选项卡怎么设置_EXCEL入门之设置
  5. python爬取新闻存入数据库_python 爬取古诗文存入mysql数据库的方法
  6. 通过Azure Kinect DK 基于Ubuntu18.04实现室内三维重建(一)
  7. 录像回放丨2020数据技术嘉年华现场视频现已上线
  8. 一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  9. 【我的物联网成长记1】如何进行端到端开发?
  10. 开发者的福利,报名即可领取代金券,赢运动手环