Tag: 任务 并行库

以非阻塞方式调用TaskCompletionSource.SetResult

我发现了TaskCompletionSource.SetResult(); 在返回之前调用等待任务的代码。 在我的情况下,导致死锁。 这是一个在普通Thread启动的简化版本 void ReceiverRun() while (true) { var msg = ReadNextMessage(); TaskCompletionSource task = requests[msg.RequestID]; if(msg.Error == null) task.SetResult(msg); else task.SetException(new Exception(msg.Error)); } } 代码的“异步”部分看起来像这样。 await SendAwaitResponse(“first message”); SendAwaitResponse(“second message”).Wait(); Wait实际上嵌套在非异步调用中。 SendAwaitResponse(简化) public static Task SendAwaitResponse(string msg) { var t = new TaskCompletionSource(); requests.Add(GetID(msg), t); stream.Write(msg); return t.Task; } 我的假设是第二个SendAwaitResponse将在ThreadPool线程中执行,但它会在为ReceiverRun创建的线程中继续。 无论如何设置任务的结果而不继续等待代码? 该应用程序是一个控制台应用程

在另一个线程中运行WPF控件

我在我的项目中使用了一个可视化控件,它来自一个我没有源代码的库。 更新(大约200毫秒)以获得良好的UI响应时间需要很长时间,其中三个控件同时在屏幕上显示。 (我可能需要一次更新所有三个,这使得我的UI在他们都在思考的时候停留了大约600毫秒)。 我已经阅读了一些关于TaskSchedulers的post,并开始研究并行任务function,作为在自己的线程中运行每个控件的一种方式。 该平台将是多核的,所以我想利用同步处理。 问题是我甚至不知道我不知道如何解决这个问题。 是否有合适的设计模式用于在WPF中的主UI线程的单独线程中运行控件? 具体来说 :它是第三方地图控件,当给定新位置或缩放级别时需要太长时间才能重绘(~200ms)。 或许其中有三个更新最高为4Hz – 显然他们无法跟上.. 我已经在用户控件中封装了WPF控件,并且需要在它自己的线程中运行每个实例,同时仍然捕获用户输入(例如,鼠标点击)。 更新 :当我感觉到解决方案时,到目前为止我已经实现了以下内容。 我的主(UI)线程产生一个线程,该线程创建一个包含相关控件的新窗口,并将其定位在正确的位置(这样它看起来只是一个普通的控件)。 _leftTopThread = new Thread(() => { _topLeftMap = new MapWindow() { WindowStartupLocation = WindowStartupLocation.Manual, Width = leftLocation.Width, Height = leftLocation.Height, Left = leftLocation.X, Top = leftLocation.Y, CommandQueue = _leftMapCommandQueue, }; _topLeftMap.Show(); System.Windows.Threading.Dispatcher.Run(); }); _leftTopThread.SetApartmentState(ApartmentState.STA); _leftTopThread.IsBackground = true; _leftTopThread.Name = […]

Parallel.ForEach不断产生新线程

当我在我的程序中使用Parallel.ForEach时,我发现有些线程似乎永远不会完成。 实际上,它一直在反复产生新的线程,这种行为是我没想到的,绝对不想要的。 我能够使用以下代码重现此行为,就像我的“真实”程序一样,它们都使用处理器和内存(.NET 4.0代码): public class Node { public Node Previous { get; private set; } public Node(Node previous) { Previous = previous; } } public class Program { public static void Main(string[] args) { DateTime startMoment = DateTime.Now; int concurrentThreads = 0; var jobs = Enumerable.Range(0, 2000); Parallel.ForEach(jobs, delegate(int jobNr) { Interlocked.Increment(ref concurrentThreads); int […]

在基于事件的异步模式上使用任务并行库

我正在写一个网络应用程序。 邮件通过传输方式发送: Network.SendMessage (new FirstMessage() ); 我可以注册一个事件处理程序,当这个消息类型到达时调用,如下所示: Network.RegisterMessageHandler (OnFirstMessageReceived); 事件被解雇了: public void OnFirstMessageReceived(EventArgs e) { } 我正在为我的网络应用程序编写自定义身份validation过程,这需要大约五条消息才能完成。 不使用任务并行库,我将被迫编写前面的事件处理程序中的每个过程的下一步,如下所示: public void OnFirstMessageReceived(EventArgs e) { Network.SendMessage( new SecondMessage() ); } public void OnSecondMessageReceived(EventArgs e) { Network.SendMessage( new ThirdMessage() ); } public void OnThirdMessageReceived(EventArgs e) { Network.SendMessage( new FourthMessage() ); } public void OnFourthMessageReceived(EventArgs e) { // Authentication […]

将ManualResetEvent包装为等待任务

我想等待手动重置事件,超时并观察取消。 我想出了类似下面的东西。 手动重置事件对象由我无法控制的API提供。 有没有办法在不接受和阻止ThreadPool的线程的情况下实现这一点? static Task TaskFromWaitHandle(WaitHandle mre, int timeout, CancellationToken ct) { return Task.Run(() => { bool s = WaitHandle.WaitAny(new WaitHandle[] { mre, ct.WaitHandle }, timeout) == 0; ct.ThrowIfCancellationRequested(); return s; }, ct); } // … if (await TaskFromWaitHandle(manualResetEvent, 1000, cts.Token)) { // true if event was set } else { // false if […]

缺少非捕获Task.Yield迫使我使用Task.Run,​​为什么要这样做呢?

如果这个问题是基于意见的,请提前道歉。 这里已经讨论了缺少不捕获执行上下文的Task.Yield版本。 显然,此function在早期版本的Async CTP中以某种forms出现,但由于它很容易被滥用而被删除 。 IMO,这样的function可能像Task.Run本身一样容易被滥用。 这就是我的意思。 想象一下,有一个等待的SwitchContext.Yield API来调度ThreadPool上的延续,因此执行将始终在与调用线程不同的线程上继续。 我可以在下面的代码中使用它,它从UI线程启动一些CPU绑定的工作。 我认为这是一种在池线程上继续CPU绑定工作的便捷方式: class Worker { static void Log(string format, params object[] args) { Debug.WriteLine(“{0}: {1}”, Thread.CurrentThread.ManagedThreadId, String.Format(format, args)); } public async Task UIAction() { // UI Thread Log(“UIAction”); // start the CPU-bound work var cts = new CancellationTokenSource(5000); var workTask = DoWorkAsync(cts.Token); // possibly await for […]

使用await时Monitor.Exit上的SynchronizationLockException

我正在创建一段代码,从我们拥有的遗留系统中获取网页。 为了避免过多的查询,我正在缓存获得的URL。 我正在使用Monitor.Enter , Monitor.Exit和双重检查以避免该请求被发出两次,但是当使用Monitor.Exit释放锁时,我收到此exception: System.Threading.SynchronizationLockException was caught HResult=-2146233064 Message=Object synchronization method was called from an unsynchronized block of code. Source=MyApp StackTrace: at MyApp.Data.ExProvider.d__0.MoveNext() in c:\Users\me\Documents\Visual Studio 2013\Projects\MyApp\MyApp\Data\ExProvider.cs:line 56 — End of stack trace from previous location where exception was thrown — at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at MyApp.Data.ExProvider.d__15.MoveNext() in c:\Users\me\Documents\Visual Studio […]

如果在没有完成任务的情况下超时,Task.Wait(int)是否会停止任务?

我有一个任务,我希望它可以在一秒钟内运行,但如果需要的时间超过几秒钟,我想取消任务。 例如: Task t = new Task(() => { while (true) { Thread.Sleep(500); } }); t.Start(); t.Wait(3000); 请注意,等待3000毫秒后,等待到期。 超时到期或任务是否仍在运行时,任务是否被取消?

如何依靠I / O大量正确地并行工作

我正在构建一个必须处理大量数据的控制台应用程序。 基本上,应用程序从数据库中获取引用。 对于每个引用,解析文件的内容并进行一些更改。 这些文件是HTML文件,并且该过程正在使用RegEx替换进行繁重的工作(查找引用并将它们转换为链接)。 然后将结果存储在文件系统中并发送到外部系统。 如果我按顺序恢复该过程: var refs = GetReferencesFromDB(); // ~5000 Datarow returned foreach(var ref in refs) { var filePath = GetFilePath(ref); // This method looks up in a previously loaded file list var html = File.ReadAllText(filePath); // Read html locally, or from a network drive var convertedHtml = ParseHtml(html); File.WriteAllText(destinationFilePath); // Copy the […]

将async / await转换为Task.ContinueWith

这个问题是由对这个问题的评论引发的: 如何在没有Microsoft.Bcl.Async情况下将非线性async/await代码反向移植到.NET 4.0? 在链接的问题中,我们有一个WebRequest操作,如果它一直失败,我们想要重试有限次数。 Async/await代码可能如下所示: async Task GetResponseWithRetryAsync(string url, int retries) { if (retries < 0) throw new ArgumentOutOfRangeException(); var request = WebRequest.Create(url); while (true) { WebResponse task = null; try { task = request.GetResponseAsync(); return (HttpWebResponse)await task; } catch (Exception ex) { if (task.IsCanceled) throw; if (–retries == 0) throw; // rethrow last error […]