Tag: task parallel library

并行生成UI

我们有一个WPF应用程序,它有一个带有缓存的VirtualizingStackPanel的ListBox。 不是因为它有大量的元素(在极端情况下通常小于20但可能高达100或更多),但因为元素需要时间来生成。 这些元素实际上是UIElement对象。 因此应用程序动态地需要生成UIElements。 问题在于,即使虚拟化似乎有效,但应用程序仍然很难做出响应,这是一个概念validation解决方案,具有最小的“噪音”。 所以我们认为,由于主要问题是我们动态生成复杂的UIElement对象,我们需要并行执行,即离线。 但是我们得到一个代码需要在STA线程上运行的错误: 调用线程必须是STA,因为许多UI组件都需要这个。 这是否意味着我们无法在WPF主UI线程以外的线程上生成UI(UIElement对象)? 这是我们的概念validation解决方案中的相关代码片段: public class Person : ObservableBase { // … UIElement _UI; public UIElement UI { get { if (_UI == null) { ParallelGenerateUI(); } return _UI; } } private void ParallelGenerateUI() { var scheduler = TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.StartNew(() => GenerateUI()) .ContinueWith(t => { _UI = t.Result; RaisePropertyChanged(“UI”); […]

使用c#并行下载多个文件

我想用C#并行下载文件。 为此,我编写了这个代码,它运行得很好,但问题是UI很冷。 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; namespace FileDownloader { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : […]

通过等待每个任务异步转换IEnumerable <Task >

今天我想知道如何通过等待每个任务来转换任务列表。 请考虑以下示例: private static void Main(string[] args) { try { Run(args); Console.ReadLine(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.ReadLine(); } } static async Task Run(string[] args) { //Version 1: does compile, but ugly and List overhead var tasks1 = GetTasks(); List gainStrings1 = new List(); foreach (Task task in tasks1) { gainStrings1.Add(await task); } Console.WriteLine(string.Join(“”, […]

TPL等待任务以特定的返回值完成

我想向X提出不同的Web服务请求,每个Web服务都返回true或false 。 这些任务应该并行执行,我想等待第一个以真值完成的任务。 当我收到真正的价值时,我不想等待其他任务完成。 在下面的示例中,不应等待 t1因为t3首先完成并返回true : var t1 = Task.Run(() => { Thread.Sleep(5000); Console.WriteLine(“Task 1 Excecuted”); return true; }, cts.Token); var t2 = Task.Run(() => { Console.WriteLine(“Task 2 Executed”); return false; }, cts.Token); var t3 = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine(“Task 3 Executed”); return true; }, cts.Token); 基本上我正在寻找具有谓词的Task.WhenAny ,当然不存在。

调用Task.WaitAll()时如何设置任务的用户身份?

我遇到了并行调用WCF服务的问题。 我正在尝试使用Tasks来并行调用两个服务以节省一些时间(我不是试图使这个异步),但我的任务是作为另一个用户运行的。 这两种服务都需要Windows身份validation,并且两次调用都会失败,因为调用该服务的用户没有所需的权限。 调用代码(下面的代码)位于ASP.NET MVC4中的Controller Action内,运行IIS 7.5。 涉及的所有应用程序池都设置为允许ASP.NET模拟并需要Windows身份validation(所有其他方法设置为禁用)。 // Parallel service request to two services Task[] tasks = new Task[2]; // this shows my credentials, eg “MYDOMAIN\\MyUsername” var userMe = System.Security.Principal.WindowsIdentity.GetCurrent().Name; tasks[0] = Task.Factory.StartNew(() => { // this shows “IIS APPPOOL\\DefaultAppPool” var user = System.Security.Principal.WindowsIdentity.GetCurrent().Name; var data = client1.MyMethod(); return data; }); tasks[1] = Task.Factory.StartNew(() […]

管道,多路复用和无界缓冲

(注意:我使用的是.Net 4, 而不是 .Net 4.5,所以我不能使用TPL的DataflowBlock类。) TL; DR版本 最后,我只是想找到一种方法来处理使用多个线程的顺序工作项,以便在最终输出中保留它们的顺序,而不需要无限制的输出缓冲区。 动机 我现有的代码提供了一个multithreading机制来处理多个数据块,其中一个I / O绑定线程(“供应商”)负责排队数据块以进行处理。 这些数据块包括工作项。 一个或多个线程(“处理器”)负责一次使一个工作项出列,然后处理这些工作项,然后在将其下一个工作项出列之前将处理后的数据写入输出队列。 最终的I / O绑定线程(“使用者”)负责从输出队列中出列已完成的工作项并将它们写入最终目标。 这些工作项目(并且必须)按照它们入队的顺序编写。 我使用并发优先级队列实现了这一点,其中每个项目的优先级由其源索引定义。 我正在使用这种方案在大数据流上进行一些自定义压缩,其中压缩本身相对较慢但是未压缩数据的读取和压缩数据的写入相对较快(尽管受I / O限制)。 我以64K的相当大的块处理数据,因此管道的开销相对较小。 我目前的解决方案运行良好,但它涉及6年前使用许多同步事件编写的大量自定义代码,并且设计看起来有些笨拙; 因此,我已经开始学术练习,看看它是否可以使用更现代的.Net库进行重写。 新设计 我的新设计使用了BlockingCollection类,并且基于这篇Microsoft文章 。 特别是,请查看标题为使用多个生产者进行负载平衡的部分。 我尝试过使用这种方法,因此我有几个处理任务,每个任务都从共享输入BlockingCollection获取工作项,并将完成的项写入自己的BlockingCollection输出队列。 因为每个处理任务都有自己的输出队列,所以我试图使用BlockingCollection.TakeFromAny()来取消第一个可用的已完成工作项。 多路复用器问题 到目前为止一切顺利,但现在问题来了。 微软文章指出: 差距是个问题。 管道的下一个阶段,即显示图像阶段,需要按顺序显示图像,并且序列中没有间隙。 这是多路复用器的用武之地。使用TakeFromAny方法,多路复用器等待来自两个filter阶段生产者队列的输入。 当图像到达时,多路复用器查看图像的序列号是否是预期序列中的下一个。 如果是,则多路复用器将其传递到显示图像阶段。 如果图像不是序列中的下一个图像,则多路复用器将值保存在内部前瞻缓冲区中,并对没有前瞻值的输入队列重复获取操作。 此算法允许多路复用器以确保顺序排序而不对值进行排序的方式将来自传入生成器队列的输入组合在一起。 好的,所发生的是处理任务可以几乎任何顺序生成完成的项目。 多路复用器负责以正确的顺序输出这些项目。 然而… 想象一下,我们有1000件待处理的物品。 进一步想象一下,由于一些奇怪的原因,第一个项目需要更长的时间来处理所有其他项目的组合。 使用我当前的方案,多路复用器将继续读取和缓冲来自所有处理输出队列的项目,直到它找到它应该输出的下一个项目。 由于它等待的项目(根据我的“想象如果”)仅在处理完所有其他工作项后才出现,我将有效地缓冲整个输入中的所有工作项! 数据量太大,无法实现。 当输出队列达到某个最大大小时(即它是一个有界的输出队列),我需要能够停止处理任务输出已完成的工作项,除非工作项恰好是多路复用器正在等待的工作项。 这就是我有点陷入困境的地方。 我可以想出很多方法来实际实现它,但它们似乎都过于复杂,以至于它们并不比我想要替换的代码更好! 我的问题是什么? 我的问题是:我是否以正确的方式解决这个问题? 我本以为这是一个众所周知的问题,但是我的研究只发现了一些文章,这些文章似乎忽略了如果工作项与其他所有工作项相比需要很长时间而发生的无限缓冲问题。 […]

解决.NET 4.0中SynchronizationContext.Current为空的问题

在.NET 4.0的主线程上, SynchronizationContext.Current意外为空的问题的解决方法是什么? 看到: 在主UI线程的Continuation中,SynchronizationContext.Current为null

使用Task.Run调用异步方法似乎错了?

我最近遇到了这个由我们为我们工作的承包商编写的代码。 它要么是非常聪明或愚蠢(我认为后者,但我想要第二个意见)。 我不是在await async速度。 基本上它的工作方式如下: public bool Send(TemplatedMessageDto message) { return Task.Run(() => SendAsync(message)) .GetAwaiter() .GetResult(); } public async Task SendAsync(TemplatedMessageDto message) { //code doing stuff var results = await _externalresource.DothingsExternally(); //code doing stuff } 现在据我所知,第一个Task.Run()是没有意义且效率低下的? 应该是: public bool Send(TemplatedMessageDto message) { return SendAsync(message)) .GetAwaiter() .GetResult(); } public async Task SendAsync(TemplatedMessageDto message) { //code doing […]

使用线程池而不是异步IO的HttpClient.SendAsync?

所以我一直在通过Reflector挖掘HttpClient.SendAsync的实现。 我有意想知道的是这些方法的执行流程,以及确定调用哪个API来执行异步IO工作。 在探索了HttpClient的各种类之后,我在内部看到它使用HttpClientHandler ,它派生自HttpMessageHandler并实现其SendAsync方法。 这是HttpClientHandler.SendAsync的实现: protected internal override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(“request”, SR.net_http_handler_norequest); } this.CheckDisposed(); this.SetOperationStarted(); TaskCompletionSource source = new TaskCompletionSource(); RequestState state = new RequestState { tcs = source, cancellationToken = cancellationToken, requestMessage = request }; try { HttpWebRequest request2 = this.CreateAndPrepareWebRequest(request); state.webRequest = […]

如何在没有抛出exception的情况下取消等待超时的任务

使用取消令牌取消具有超时(在超时结束之前)的任务时,将引发exception。 例: mytask.start(); bool didTaskRunInTime = mytask.wait(5 mins, _cancelToken); 这意味着我不能继续下面。 //was the task cancelled if (_cancelToken.IsCancelRequested) { // log cancel from user to file etc } if (didTaskRunInTime ) { int taskResult = myTask.Result; // log result to file } else if (!_cancelToken.IsCancelRequested) { // Tell user task timed out , log a message etc […]