Tag: task parallel library

当等待是最后一次时,不必要的异步/等待?

我最近一直在处理异步等待 (阅读包括斯蒂芬和乔恩最后两章在内的所有可能的文章),但我得出结论,我不知道它是否100%正确。 – 因此我的问题。 由于async只允许单词等待存在,我将把async放在一边。 AFAIU等待着继续。 而不是编写function(连续)代码,写同步代码。 (我想将其称为可回调代码) 因此,当编译器到达await – 它将代码分成2个部分,并在第一部分完成后注册要执行的第二部分( 我不知道为什么不使用单词callback – 这正是所做的 ) 。 (同时工作 – 线程回来做其他事情)。 但看看这段代码: public async Task ProcessAsync() { Task workTask = SimulateWork(); string st= await workTask; //do something with st } public Task SimulateWork() { return … } 当线程到达await workTask; 它将方法分为2个部分。 所以在SimulateWork完成之后 – 方法的继续:AKA: //do something with st执行//do […]

使用ConfigureAwait进行C#async / await链接(false)

基于众多书籍和博客,包括这里的优秀书籍,很明显当一个人写一个暴露助手异步方法的DLL库,即包装器方法时,通常认为内部完成实际异步方法的I / O任务的最佳实践在这样的线程池线程上(为了简洁起见,下面显示了伪代码,我以HttpClient为例) public Async Task MyMethodAsync(..) { … var httpClient = new HttpClient(..); var response = await httpClient.PostAsJsonAsync(..).ConfigureAwait(false); … return response; } 这里的关键是使用ConfigureAwait(false)以便在线程池线程上而不是在原始线程上下文上发生IO任务完成,从而可能防止死锁。 我的问题是从来电者的角度来看。 我对调用者和上面的方法调用之间存在多层方法调用的情况特别感兴趣,如下例所示。 CallerA -> Method1Async -> Method2Async -> finally the above MyMethodAsync 仅对最终方法使用ConfigureAwait(false)是否足够,还是应该确保Method1Async和Method2Async还在内部使用ConfigureAwait(false)调用其异步方法? 将它包含在所有这些中间方法中似乎很愚蠢,特别是如果Method1Async和Method2Async只是最终调用MyMethodAsync重载。 有任何想法,请指教! 更新了示例所以如果我有一个包含以下私有异步方法的库, private async Task MyPrivateMethodAsync(MyClass myClass) { … return await SomeObject.ReadAsStringAsync().ConfigureAwait(false); } 我应该确保以下公共重载方法还包括ConfigureAwait(false),如下所示? public async Task […]

嵌套的Parallel.ForEach循环在同一个列表中?

我需要并行化一个方法,该方法对列表中的元素进行详尽的成对比较。 串行实现很简单: foreach (var element1 in list) foreach (var element2 in list) foo(element1, element2); 在这种情况下,foo不会改变element1或element2的状态。 我知道简单地执行嵌套的Parallel.ForEach语句是不安全的: Parallel.ForEach(list, delegate(A element1) { Parallel.ForEach(list, delegate(A element2) { foo(element1, element2); }); }); 使用并行任务库实现此目的的理想方法是什么?

任务继续与async / await并行执行

在使用async / await结构的控制台应用程序的上下文中,我想知道“continuation”是否可以在不同CPU上的多个线程上并行运行。 我认为就是这种情况,因为延迟发布在默认任务调度程序(控制台应用程序中没有SynchronizationContext)上,这是线程池。 我知道async / await构造不构造任何额外的线程。 仍然应该由线程池为每个CPU构建至少一个线程,因此如果在线程池上发布了continuation,它可以在不同的CPU上并行调度任务延续…这就是我的想法,但出于某种原因我昨天对此我真的很困惑,我不再那么肯定了。 这是一些简单的代码: public class AsyncTest { int i; public async Task DoOpAsync() { await SomeOperationAsync(); // Does the following code continuation can run // in parrallel ? i++; // some other continuation code …. } public void Start() { for (int i=0; i<1000; i++) { var _ = […]

如何更好地理解“异步 – 处理多个exception”一文中的代码/语句?

运行以下C#控制台应用程序 class Program { static void Main(string[] args) { Tst(); Console.ReadLine(); } async static Task Tst() { try { await Task.Factory.StartNew (() => { Task.Factory.StartNew (() => { throw new NullReferenceException(); } , TaskCreationOptions.AttachedToParent ); Task.Factory.StartNew ( () => { throw new ArgumentException(); } ,TaskCreationOptions.AttachedToParent ); } ); } catch (AggregateException ex) { // this […]

如何从并发运行的任务更新进度条

我尝试将并行任务绑定到包含pprogressBars的listView。 我使用的是有限的调度程序,只允许指定的最大并行度。 到目前为止它大部分时间都可以正常工作,但有时两个任务会更新listView中的相同进度条。 以下是我的代码。 知道如何防止两个任务更新listView中的相同进度条吗? 或者如何从同时运行的任务更新进度条? public class MyClass { public ObservableCollection StatusItems { get; set; } private Object thisLock = new Object(); public int Process() //handled { StatusItems = new ObservableCollection(); for (int i = 0; i < 4; i++) // initialize progress bar collection { StatusInfo sInfo = new StatusInfo(); sInfo.ThreadID = i; […]

TPL Dataflow,如何将项目转发到许多链接目标块中的一个特定目标块?

我正在寻找一个TPL数据流块解决方案,它可以容纳多个项目,它可以链接到多个目标块,但是它能够将项目转发到仅通过filter/谓词的特定目标块。 任何时候都不应该将项目同时传递给多个目标块,始终只能与匹配filter的项目一起传递,否则该项目可以被丢弃。 我不喜欢BroadCastBlock,因为如果我理解正确,它不能保证传送(或者是吗?)并且过滤是在目标块侧完成的,这意味着BroadCastBlock基本上将每个项目的副本发送到所有linkedTo目标块。 如果我理解正确的话,它也不会在任何时候持有多个项目。 我不想使用Post / Async但维护LinkTo链。 是否有办法绕过完整的自定义数据流块? 或者我误解了BroadCastBlock的工作原理? 不幸的是,实际上没有太多文档可以详细介绍并涵盖用例。 任何想法都受到高度赞赏。

如果引发任何exception,如何在Task.WhenAll上取消并引发exception?

我正在使用Task.WhenAll等待倍数任务。 当其中一个生成exception时,我希望Task.WhenAll(或任何其他等待多个任务的方式)立即取消其他任务并引发exception。 可能吗? 提前致谢

如何正确执行Parallel.ForEach,锁定和进度报告

我正在尝试实现Parallel.ForEach模式并跟踪进度,但我遗漏了一些关于锁定的内容。 以下示例在threadCount = 1时计数为1000,但在threadCount > 1时不threadCount 。正确的方法是什么? class Program { static void Main() { var progress = new Progress(); var ids = Enumerable.Range(1, 10000); var threadCount = 2; Parallel.ForEach(ids, new ParallelOptions { MaxDegreeOfParallelism = threadCount }, id => { progress.CurrentCount++; }); Console.WriteLine(“Threads: {0}, Count: {1}”, threadCount, progress.CurrentCount); Console.ReadKey(); } } internal class Progress { private […]

通过异步同步避免死锁并防止UI响应

我们有一个由WPF和/或Winforms客户端使用的库。 我们提供了一个类似于的异步方法: Task GetIntAsync() 我们(不幸的是)还提供了一个同步包装器方法: int GetInt(); 它基本上只是调用异步方法并调用.Result来完成它的任务。 我们最近意识到在某些情况下GetIntAsync一些代码需要在主UI线程上运行(它需要使用标记为“单个”线程模型的传统COM组件(即组件必须在主STA线程中运行而不仅仅是任何STA线程) 所以问题是当在主线程上调用GetInt()时,它将会死锁 .Result阻塞主线程, GetIntAsync()的代码使用Dispatcher.Invoke尝试在主线程上运行。 同步方法已被消耗,因此删除它将是一个重大变化。 因此,我们选择在同步GetInt()方法中使用WaitWithPumping来允许调用主线程。 除了从UI代码中使用GetInt()客户端之外,这种方法GetInt() 。 以前,他们预计使用GetInt()会使UI无法响应 – 也就是说,如果他们从按钮的click事件处理程序中调用GetInt() ,他们会期望在处理程序返回之前不会处理任何Windows消息。 现在消息被抽取,他们的UI响应,并且可以再次点击相同的按钮(并且他们可能不会将其处理程序编码为可重入)。 如果有合理的解决方案,我们希望我们的客户不需要在调用GetInt期间针对响应的UI进行GetInt 题: 有没有办法做一个WaitWithPumping ,它将泵出“调用主要”消息,但不会WaitWithPumping其他与UI相关的消息? 如果客户端UI的行为就像当前显示模式对话框一样,虽然是隐藏的(即用户无法访问其他窗口),但这足以满足我们的目的。 但是,从我读到的内容来看,你无法隐藏modal dialog。 您可以想到的其他解决方法将不胜感激。