在性能方面,会这2种方法运行GetAllWidgets()和GetAllFoos()并行?
有没有理由使用一个而不是另一个?在编译器的幕后似乎发生了很多事情,所以我觉得不清楚.
=============方法A:使用多个等待======================
public async Task<IHttpActionResult> MethodA()
{
var customer = new Customer();
customer.Widgets = await _widgetService.GetAllWidgets();
customer.Foos = await _fooService.GetAllFoos();
return Ok(customer);
}
Run Code Online (Sandbox Code Playgroud)
===============方法B:使用Task.WaitAll =====================
public async Task<IHttpActionResult> MethodB()
{
var customer = new Customer();
var getAllWidgetsTask = _widgetService.GetAllWidgets();
var getAllFoosTask = _fooService.GetAllFos();
Task.WaitAll(new List[] {getAllWidgetsTask, getAllFoosTask});
customer.Widgets = getAllWidgetsTask.Result;
customer.Foos = getAllFoosTask.Result;
return Ok(customer);
}
Run Code Online (Sandbox Code Playgroud)
=====================================
我们目前正在开发一个Web应用程序,它依赖于ASP .NET MVC 5,Angular.JS 1.4,Web API 2和Entity Framework 6.出于可伸缩性的原因,Web应用程序的重量依赖于async/await模式.我们的域需要一些cpu密集型计算,这可能需要几秒钟(<10s).在过去,一些团队成员使用Task.Run,以加快计算速度.因为在ASP .NET MVC或Web API控制器中启动一个额外的线程被认为是一种不好的做法(该线程不为IIS所知,所以不是在AppDomain Recycle上考虑=>参见Stephen Cleary的博客文章),他们使用了ConfigureAwait(false).
public async Task CalculateAsync(double param1, double param2)
{
// CalculateSync is synchronous and cpu-intensive (<10s)
await Task.Run(() => this.CalculateSync(param1, param2))).ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用新任务,但发生了一些我不明白的事情.
首先,代码非常简单.我传入一些图像文件的路径列表,并尝试添加一个任务来处理它们中的每一个:
public Boolean AddPictures(IList<string> paths)
{
Boolean result = (paths.Count > 0);
List<Task> tasks = new List<Task>(paths.Count);
foreach (string path in paths)
{
var task = Task.Factory.StartNew(() =>
{
Boolean taskResult = ProcessPicture(path);
return taskResult;
});
task.ContinueWith(t => result &= t.Result);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
return result;
}
Run Code Online (Sandbox Code Playgroud)
我发现,如果我让它运行,例如,单元测试中的3个路径列表,则所有三个任务都使用提供列表中的最后一个路径.如果我单步执行(并减慢循环的处理速度),则使用循环中的每个路径.
有人可以解释一下发生了什么,为什么?可能的解决方法?
在这个问题之后,我试图使用TPL实现异步方法,并尝试遵循TAP指南.
我希望我的异步方法在完成后执行回调.据我所知,有三种方法可以做到这一点.
1)在我的任务委托中手动回调
public Task DoWorkAsync(DoWorkCompletedCallback completedCallback)
{
return Task.Factory.StartNew(
{
//do work
//call callback manually
completedCallback();
});
}
Run Code Online (Sandbox Code Playgroud)
2)在任务委托中为任务分配回调
public Task DoWorkAsync(DoWorkCompletedCallback completedCallback)
{
return Task.Factory.StartNew(
{
//do work
}
).ContinueWith(completedCallback); //assign callback to Task
}
Run Code Online (Sandbox Code Playgroud)
3)在呼叫者中为任务分配回叫
public Task DoWorkAsync()
{
return Task.Factory.StartNew(
{
//do work
});
}
public void SomeClientCode()
{
Task doingWork = DoWorkAsync();
doingWork.ContinueWith(OnWorkCompleted);
}
Run Code Online (Sandbox Code Playgroud)
我的直觉是3更正确,因为它将回调与方法分离,并且意味着客户端代码可以以任何方式管理任务(使用回调,轮询等),这似乎是任务的全部内容.但是,如果DoWorkAsync()在客户端代码挂钩其回调之前完成其工作会发生什么?
是否有一种普遍接受的方式来做到这一点还是全新的?
做2)超过1)有什么好处吗?
我对通过Post()或SendAsync()发送项目之间的区别感到困惑.我的理解是,在所有情况下,一旦项目到达数据块的输入缓冲区,控制权将返回到调用上下文,对吗?那为什么我需要SendAsync?如果我的假设不正确,那么我想,相反,如果使用数据块的整个想法是建立并发和异步环境,为什么有人会使用Post().
我当然理解技术上的差异,Post()返回一个bool,而SendAsync返回一个等待bool的任务.但是它有什么影响呢?何时返回bool(我理解是否确认该项是否放在数据块的队列中)会被延迟?我理解async/await并发框架的一般概念,但在这里并没有多大意义,因为除了bool之外,对传入项所做的任何操作的结果都不会返回给调用者,而是放在一个"out-queue"并转发到链接数据块或丢弃.
发送项目时两种方法之间是否存在性能差异?
c# concurrency message-passing task-parallel-library tpl-dataflow
我有这个构造main(),它创造了
var tasks = new List<Task>();
var t = Task.Factory.StartNew(
async () =>
{
Foo.Fim();
await Foo.DoBar();
});
//DoBar not completed
t.Wait();
//Foo.Fim() done, Foo.DoBar should be but isn't
Run Code Online (Sandbox Code Playgroud)
但是,当我.Wait为t时,它不会等待呼叫DoBar()完成.我怎么让它实际等待?
我听说任务并行库可以在.Net 3.5项目中使用.这是否正确,如果是,我该如何使用它?在.Net 4.0中,它驻留在System.Threading中,但是当我在Visual Studio 2010中选择.Net 3.5作为目标时,我无法访问Parallel和Parallel循环等类.
我在.NET 4.0中使用TPL(任务并行库).我想通过使用Thread.GetDomain().UnhandledException事件集中处理所有未处理异常的处理逻辑.但是,在我的应用程序中,从未使用TPL代码启动的线程触发事件,例如Task.Factory.StartNew(...).如果我使用类似的东西,事件确实会被解雇new Thread(threadStart).Start().
这篇MSDN文章建议使用Task.Wait()来捕获AggregateException使用TPL的时间,但这不是我想要的,因为这种机制不够"集中".
有没有人遇到过同样的问题,还是仅仅是我?你对此有什么解决方案吗?
.net multithreading .net-4.0 task-parallel-library unobserved-exception
假设我们有一个I/O绑定方法(例如进行DB调用的方法).此方法可以同步和异步运行.那是,
同步:
IOMethod()
Run Code Online (Sandbox Code Playgroud)异步:
BeginIOMethod()
EndIOMethod()
Run Code Online (Sandbox Code Playgroud)然后,当我们以不同的方式执行方法时,如下所示,在资源利用方面的性能差异是什么?
var task = Task.Factory.StartNew(() => { IOMethod(); });
task.Wait();
Run Code Online (Sandbox Code Playgroud)var task = Task.Factory.FromAsync(BeginIOMethod, EndIOMethod, ... );
task.Wait();
Run Code Online (Sandbox Code Playgroud)我想知道如何以"正确"的方式编写自己的异步方法.
我看过许多帖子解释async/await模式,如下所示:
http://msdn.microsoft.com/en-us/library/hh191443.aspx
// Three things to note in the signature:
// - The method has an async modifier.
// - The return type is Task or Task<T>. (See "Return Types" section.)
// Here, it is Task<int> because the return statement returns an integer.
// - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();
// GetStringAsync returns a Task<string>. That means …Run Code Online (Sandbox Code Playgroud) c# ×8
.net ×6
async-await ×4
asynchronous ×3
.net-3.5 ×1
.net-4.0 ×1
asp.net ×1
asp.net-mvc ×1
callback ×1
concurrency ×1
task ×1
tpl-dataflow ×1