我想了解为什么和什么时候应该使用async控制器操作。 最后,当我用它等待,它将等待操作完成,以返回视图。 例如 public async Task<ActionResult> TryMe() { await SomeActionAsync(); return View(); } 在这种情况下,如果我使用async或不使用async ,则Action将执行相同的时间。 如果我不想并行运行至less两个慢速操作(不依赖于对方),我看不到有任何理由使用async控制器操作。 如果我错了,请纠正我。 我想我在这里错过了一些东西。
什么时候会select在TPL上使用Rx还是两个框架是正交的? 据我所知,Rx主要是为了提供对事件的抽象,允许合成,但它也允许提供对asynchronous操作的抽象。 使用Createxx重载和Fromxxx重载并通过处置IDisposable返回取消。 TPL还通过任务和取消function提供了操作抽象。 我的困境是什么时候使用哪个和哪些场景?
我试图围绕TPL,C#5中新的async / awaitfunction,以及TaskCompletionSource的奥秘。 有一件事情我不清楚的是什么时候使用SetResult , SetException和SetCancel与TrySetResult , TrySetException和TrySetCancel 。 这是MSDN必须说的: 如果任务已处于三种最终状态之一,则此操作将返回false:RanToCompletion,Faulted或Canceled。 如果基础任务已经被处置,这个方法也返回false。 好吧,我明白了,但它并没有真正提供任何指导什么时候或为什么要使用一个。 那么,交易是什么?
考虑一个拥有大量需要处理的作业的队列。 队列的限制是一次只能得到1份工作,无法知道有多less工作。 这些工作需要10秒才能完成,并且涉及很多等待Web服务的响应,因此不受CPU限制。 如果我使用这样的东西 while (true) { var job = Queue.PopJob(); if (job == null) break; Task.Factory.StartNew(job.Execute); } 然后,它会激烈地从队列中挤出工作,比完成工作快得多,耗尽内存并落在它的屁股上。 > < 我不能使用(我不认为) ParallelOptions.MaxDegreeOfParallelism,因为我不能使用Parallel.Invoke或Parallel.ForEach 我find了3个替代品 用TaskreplaceTask.Factory.StartNew Task task = new Task(job.Execute,TaskCreationOptions.LongRunning) task.Start(); 这似乎有点解决问题,但我不清楚这是怎么回事 ,如果这是最好的方法。 创build一个限制并发度的自定义任务计划程序 使用像BlockingCollection这样的东西,在开始时将作业添加到集合,并在完成时移除以限制可以运行的数字。 #1我必须相信自动做出正确的决定,#2 /#3我必须计算出可以运行的最大数量的任务。 我是否正确地理解了这一点 – 哪一个更好,或者有另一种方法? 编辑 – 这是我从下面的答案,生产者 – 消费者模式。 除了整体吞吐量的目的不是让工作更快地出队比可以处理,并没有多个线程轮询队列(这里没有显示,但这是一个非阻塞操作,并将导致巨大的交易成本,如果从多个地方高频调查) 。 // BlockingCollection<>(1) will block if try to add […]
我在我的main()中创build了这个构造 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 但是,当我.Wait t时,它不会等待DoBar()的调用完成。 我如何才能真正等待?
我正在尝试玩新的任务,但有些事情我不明白。 首先,代码非常简单。 我传递一些path到一些图像文件,并尝试添加一个任务来处理它们中的每一个: 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; } 我发现,如果我让这个运行,比如一个unit testing中的3个path列表,所有这三个任务都使用提供的列表中的最后一个path。 如果我一步一步(并减慢循环的处理),则使用循环中的每条path。 有人可以解释发生了什么,为什么? 可能的解决方法?
在这个问题之后 ,我尝试使用TPL实现asynchronous方法,并尝试遵循TAP准则。 我希望我的asynchronous方法在完成时执行callback。 据我所知,有三种方法可以做到这一点。 1)在我的任务委托中手动callback public Task DoWorkAsync(DoWorkCompletedCallback completedCallback) { return Task.Factory.StartNew( { //do work //call callback manually completedCallback(); }); } 2)在任务委托中为任务分配callback public Task DoWorkAsync(DoWorkCompletedCallback completedCallback) { return Task.Factory.StartNew( { //do work } ).ContinueWith(completedCallback); //assign callback to Task } 3)将呼叫分配给主叫方的任务 public Task DoWorkAsync() { return Task.Factory.StartNew( { //do work }); } public void SomeClientCode() { […]
如果我有一个方法中的代码块(使用.NET 4和任务并行库): var task = new Task(() => DoSomethingLongRunning()); task.Start(); 方法返回,这个任务是否会超出范围,被垃圾收集,还是会运行完成? 我还没有注意到GCing的任何问题,但是要确保我不会为GC的竞争状态而设置自己。
我有一些asynchronous代码,我想添加CancellationToken。 然而,有很多不需要的实现,所以我想有一个默认参数 – 也许是CancellationToken.None。 然而, Task<x> DoStuff(…., CancellationToken ct = null) 产量 types''的值不能用作默认参数,因为没有标准转换来键入'System.Threading.CancellationToken' 和 Task<x> DoStuff(…., CancellationToken ct = CancellationToken.None) “ct”的默认参数值必须是编译时常量 有没有什么办法来取消CancellationToken的默认值?
请看下面的代码 – static void Main(string[] args) { // Get the task. var task = Task.Factory.StartNew<int>(() => { return div(32, 0); }); // For error handling. task.ContinueWith(t => { Console.WriteLine(t.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted); // If it succeeded. task.ContinueWith(t => { Console.WriteLine(t.Result); }, TaskContinuationOptions.OnlyOnRanToCompletion); Console.ReadKey(); Console.WriteLine("Hello"); } private static int div(int x, int y) { if (y == […]