什么.NET 4.5(或更早)更高级别的结构使线程更容易? [英] What .NET 4.5 (or earlier) higher-level constructs make Threading easier?

查看:149
本文介绍了什么.NET 4.5(或更早)更高级别的结构使线程更容易?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代表有几个,使线程更容易在.NET 参考对象。它们可用于异步调用的方法。在框架4.5(或更早),使使用更容易或更不容易出错的线程什么其他的对象是否存在?

Delegates are a few of the objects that make threading easier in .NET reference. They can be used to asynchronously invoke a method. What other objects exist in framework 4.5 (or earlier) that make the use of threads easier or less error prone?

什么是其他抽象使并发和多线程更容易?

What are the other abstractions make concurrency and multithreading easier?

注:此问题的更新

推荐答案

我倾向于回答了很多有关多线程问题,我经常看到要求以各种不同的方式相同的基本问题。我将present最常见的问题,因为我看到他们多年来并解释新技术方面取得了解决这些问题更容易。

I tend to answer a lot of questions related to multithreading and I often see the same basic question asked in various different ways. I will present the most common problems as I have seen them over the years and explain how the newer technologies have made solving these problems easier.

关闭了循环变量

这是不特定线程的问题,而是使用线程的绝对放大的问题。 C#5.0修复了这个问题的的foreach 通过为每个迭代一个新的变量循环。您将不再需要创建的lambda EX pression封闭的特殊变量。不幸的是,循环将仍然需要一个特殊的捕捉变量处理。

This is not a problem specific to threading, but the use of threading definitely magnifies the problem. C# 5.0 fixes this problem for the foreach loop by creating a new variable for each iteration. You will no longer have to create a special variable for lambda expression closures. Unfortunately, the for loop will still need to be handle with a special capturing variable.

等待异步任务完成

.NET 4.0引入了 CountdownEvent 类,它封装了很多等待完成许多任务所需的逻辑。最初级的开发人员使用的Thread.join 来电或单个 WaitHandle.WaitAll的通话。两者都具有可扩展性的问题。旧的模式是使用单个的ManualResetEvent ,并表示它当计数器达到零。使用互锁类的柜台进行了更新。 CountdownEvent 使这种模式更加容易。不过,别忘了把你的主要的工人,以及避免,如果一个工人完成所有的工作人员都被排队之前,可以发生的微妙的竞争状态。

.NET 4.0 introduced the CountdownEvent class which encapsulates a lot of the logic required to wait for the completion of many tasks. Most junior developers used Thread.Join calls or a single WaitHandle.WaitAll call. Both of these have scalability problems. The old pattern was to use a single ManualResetEvent and signal it when a counter reached zero. The counter was updated using the Interlocked class. CountdownEvent makes this pattern much easier. Just remember to treat your main as a worker as well to avoid that subtle race condition that can occur if one worker finishes before all workers have been queued.

.NET 4.0还引入了工作类,可以有子任务,通过 TaskCreationOptions.AttachedToParent 链连接起来。如果你调用 Task.Wait 在家长会等待所有子任务完成为好。

.NET 4.0 also introduced the Task class which can have child tasks chained off of it via TaskCreationOptions.AttachedToParent. If you call Task.Wait on a parent it will wait for all child tasks to complete as well.

生产者 - 消费者

.NET 4.0引入了 BlockingCollection 类,它的作用相似,但它可以在集合为空阻止正常的队列。你可以通过调用添加和出队的对象,通过调用排队的对象。 块,直至产品可用。这简化生产者 - 消费者的逻辑相当。它曾经是,开发商试图写自己的阻塞队列类的情况。但是,如果你不知道你在做什么,然后你就可以真正搞砸了......坏。事实上,时间最长微软已经在MSDN文档本身是严重打破了阻塞队列的例子。幸运的是,它已被删除。

.NET 4.0 introduced the BlockingCollection class which acts like a normal queue except that it can block when the collection is empty. You can queue an object by calling Add and dequeue an object by calling Take. Take blocks until an item is available. This simplifies producer-consumer logic considerably. It used to be the case that developers were trying to write their own blocking queue class. But, if you do not know what you are doing then you can really screw it up...bad. In fact, for the longest time Microsoft had a blocking queue example in the MSDN documentation that was itself badly broken. Fortunately, it has since been removed.

更新UI与工作线程的进步

的BackgroundWorker 的引入实现了从WinForm应用程序的开发新手轻松了许多分拆后台任务。主要的好处是,你可以调用 ReportProgress 的DoWork 事件处理程序,并在 ProgressChanged 的事件处理程序将被自动编组到UI线程。当然,任何人跟踪我的回答对SO知道我的感受(通过调用等)作为更新用简单的进度信息的用户界面解决方案编组作业。我撕裂它所有的时间,因为它通常是一个可怕的方式。 的BackgroundWorker 仍然会强制开发商成为推模式(通过编组在后台操作),但至少它做这一切的幕后。

The introduction of BackgroundWorker made spinning off a background task from a WinForm application a lot easier for novice developers. The main benefit is that you can call ReportProgress from within the DoWork event handler and the ProgressChanged event handlers will be automatically marshaled onto the UI thread. Of course, anyone that tracks my answers on SO knows how I feel about marshaling operations (via Invoke or the like) as a solution for updating the UI with simple progress information. I rip on it all the time because it is generally a terrible approach. BackgroundWorker still forces the developer into a push model (via marshaling operations in the background), but at least it does all of this behind the scenes.

调用的inelegance

我们都知道,一个UI元素只能从UI线程访问。这通常意味着,开发人员必须使用通过 ISynchronizeInvoke DispatcherObject的编组作业,或的SynchronizationContext 来控制转移回UI线程。但是让我们面对它。这些编组操作看起来很丑陋。 Task.ContinueWith 做这一点更优雅,但真正的荣耀去等待作为部分C#5的新的异步编程模型。 等待可以用来等待工作以这样的方式来完成流控制,而任务暂时中断正在运行,然后在正确的同步背景下,非常当场退回。没有什么更优雅和满足比使用等待,以替换那些调用的电话。

We all know that a UI element can only be accessed from the UI thread. This generally meant that a developer had to use marshaling operations via ISynchronizeInvoke, DispatcherObject, or SynchronizationContext to transfer control back to the UI thread. But lets face it. These marshaling operations look ugly. Task.ContinueWith made this a little more elegant, but the real glory goes to await as part of C# 5's new asynchronous programming model. await can be used to wait for a Task to complete in such a manner that flow control is temporarily interrupted while the task is running and then returned at that very spot in the right synchronization context. There is nothing more elegant and satisfying than using await as a replacement for all those Invoke calls.

并行编程

我经常看到的问题,询问事情如何可以并行发生。旧的方式是创建一个线程数,或使用线程池。 .NET 4.0给了使用TPL和PLINQ。该并行类是一个伟大的方式得到一个循环将并行的迭代。而PLINQ的进行AsParallel 是同一枚硬币的老式LINQ的不同侧面。这些新的第三方物流的功能大大简化了这一类多线程编程的。

I often see questions asking how things can happen in parallel. The old way was to create a few threads or use the ThreadPool. .NET 4.0 gave use the TPL and PLINQ. The Parallel class is a great way to get the iterations of a loop going in parallel. And PLINQ's AsParallel is a different side of the same coin for plain old LINQ. These new TPL features greatly simplify this category of multithreaded programming.

.NET 4.5引入了TPL数据流库。它的目的是让优雅的其他复杂的并行编程问题。它通过抽象类成块。它们可以是目标块或源块。数据可以从一个模块流向另一个。有许多不同的区块,包括 BufferBlock< T> BroadcastBlock< T> ActionBlock< T> 等,所有做不同的事情。当然,整个库将被用于新的进行了优化异步等待关键字。这是一个令人兴奋的新组类,我觉得会慢慢流行起来。

.NET 4.5 introduces the TPL Data Flow library. It is intended to make elegant an otherwise complex parallel programming problem. It abstracts classes into blocks. They can be target blocks or source blocks. Data can flow from one block to another. There are many different blocks including BufferBlock<T>, BroadcastBlock<T>, ActionBlock<T>, etc. that all do different things. And, of course, the whole library will be optimized for use with the new async and await keywords. It is an exciting new set of classes that I think will slowly catch on.

正常终止

你如何让一个线程停止?我看到这个问题有很多。最简单的方法是调用 Thread.Abort的,但我们都知道这样做的危险...我希望。有许多不同的方法来安全地做到这一点。 .NET 4.0中引入了一个通过的CancellationToken 更统一的概念,称为消除和 CancellationTokenSource 。后台任务可以查询 IsCancellationRequested 或只是叫 ThrowIfCancellationRequested 在安全点,摆好中断的任何工作,他们在做什么。其他线程可以调用取消来请求取消。

How do you get a thread to stop? I see this question a lot. The easiest way is to call Thread.Abort, but we all know the perils of doing this...I hope. There are many different ways to do this safely. .NET 4.0 introduced a more unified concept called cancellation via CancellationToken and CancellationTokenSource. Background tasks can poll IsCancellationRequested or just call ThrowIfCancellationRequested at safe points to gracefully interrupt whatever work they were doing. Other threads can call Cancel to request cancellation.

这篇关于什么.NET 4.5(或更早)更高级别的结构使线程更容易?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆