C# 委托和线程!

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/467446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:34:11  来源:igfitidea点击:

C# Delegates and Threads!

c#

提问by Kredns

What exactly do I need delegates, and threads for?

我到底需要什么委托和线程?

采纳答案by Marc Gravell

Delegates act as the logical (but safe) equivalent to function-pointers; they allow you to talk about an operation in an abstract way. The typical example of this is events, but I'm going to use a more "functional programming" example: searching in a list:

委托作为逻辑(但安全)等价于函数指针;它们允许您以抽象的方式谈论操作。典型的例子是事件,但我将使用一个更“函数式编程”的例子:在列表中搜索:

List<Person> people = ...
Person fred = people.Find( x => x.Name == "Fred");
Console.WriteLine(fred.Id);

The "lambda" here is essentially an instance of a delegate - a delegate of type Predicate<Person>- i.e. "given a person, is something true or false". Using delegates allows very flexible code - i.e. the List<T>.Findmethod can find all sorts of things based on the delegate that the caller passes in.

这里的“lambda”本质上是一个委托的实例——一个类型的委托Predicate<Person>——即“给定一个人,是真还是假”。使用委托允许非常灵活的代码 - 即该List<T>.Find方法可以根据调用者传入的委托查找各种事物。

In this way, they act largely like a 1-method interface - but much more succinctly.

通过这种方式,它们在很大程度上就像一个 1 方法接口 - 但更加简洁。

回答by BBetances

Delegates are used to add methods to events dynamically.

委托用于动态地向事件添加方法。

Threads run inside of processes, and allow you to run 2 or more tasks at once that share resources.

线程在进程内部运行,并允许您一次运行 2 个或更多共享资源的任务。

回答by Mehrdad Afshari

Delegates: Basically, a delegate is a method to reference a method. It's like a pointer to a method which you can set it to different methods that match its signature and use it to pass the reference to that method around.

委托:基本上,委托是一种引用方法的方法。它就像一个指向方法的指针,您可以将它设置为匹配其签名的不同方法,并使用它来传递对该方法的引用。

Threadis a sequentual stream of instructions that execute one after another to complete a computation. You can have different threads running simultaneously to accomplish a specific task. A thread runs on a single logical processor.

线程是一个依次执行以完成计算的连续指令流。您可以同时运行不同的线程来完成特定任务。一个线程在单个逻辑处理器上运行。

回答by Rosstified

I'd suggest have a search on these terms, there is plenty of information out there. They are pretty fundamental concepts, wiki is a high level place to start:

我建议搜索这些术语,那里有很多信息。它们是非常基本的概念,维基是一个高级的起点:

http://en.wikipedia.org/wiki/Thread_(computer_science)
http://en.wikipedia.org/wiki/C_Sharp_(programming_language)

http://en.wikipedia.org/wiki/Thread_(computer_science)
http://en.wikipedia.org/wiki/C_Sharp_(programming_language)

回答by Mark Brittingham

Concrete examples always help me so here is one for threads. Consider your web server. As requests arrive at the server, they are sent to the Web Server process for handling. It couldhandle each as it arrives, fully processing the request and producing the page before turning to the next one. But consider just how much of the processing takes place at hard drive speeds (rather than CPU speeds) as the requested page is pulled from the disk (or data is pulled from the database) before the response can be fulfilled.

具体的例子总是对我有帮助,所以这里是一个线程。考虑您的网络服务器。当请求到达服务器时,它们被发送到 Web Server 进程进行处理。它可以在每一个到达时进行处理,完全处理请求并在转到下一个页面之前生成页面。但是考虑一下有多少处理是在硬盘驱动器速度(而不是 CPU 速度)下进行的,因为请求的页面是从磁盘中提取的(或数据是从数据库中提取的),然后才能完成响应。

By pulling threads from a thread pool and giving each request its own thread, we can take care of the non-disk needs for hundreds of requests before the disk has returned data for the first one. This will permit a degree of virtual parallelism that can significantly enhance performance. Keep in mind that there is a lot more to Web Server performance but this should give you a concrete model for how threading can be useful.

通过从线程池中拉取线程并为每个请求提供自己的线程,我们可以在磁盘为第一个请求返回数据之前处理数百个请求的非磁盘需求。这将允许一定程度的虚拟并行性,可以显着提高性能。请记住,Web Server 的性能还有很多,但这应该为您提供一个具体的模型,说明线程如何发挥作用。

回答by Jo?o Augusto

Your question is to vague...

你的问题很模糊...

But you probably just want to know how to use them in order to have a window, a time consuming process running and a progress bar...

但是您可能只想知道如何使用它们来获得一个窗口、一个运行耗时的进程和一个进度条......

So create a thread to do the time consuming process and use the delegates to increase the progress bar! :)

所以创建一个线程来做耗时的过程并使用delegate来增加进度条!:)

回答by Eclipse

They are useful for the same reason high-level languages are useful. You don't need them for anything, since really they are just abstractions over what is really happening. They do make things significantly easier and faster to program or understand.

它们有用的原因与高级语言有用的原因相同。你不需要它们做任何事情,因为它们实际上只是对实际发生的事情的抽象。它们确实使编程或理解变得更加容易和快速。

回答by Matt Davis

Marc Gravell provided a nice answer for 'what is a delegate.'

Marc Gravell 为“什么是委托”提供了一个很好的答案。

Andrew Troelsen defines a thread as

Andrew Troelsen 将线程定义为

...a path of execution within a process. "Pro C# 2008 and the .NET 3.5 Platform," APress.

...流程中的执行路径。“Pro C# 2008 和 .NET 3.5 平台”,美联社。

All processes that are run on your system have at least one thread. Let's call it the main thread. You can create additional threads for any variety of reasons, but the clearest example for illustrating the purpose of threads is printing.

在您的系统上运行的所有进程都至少有一个线程。我们称它为主线程。您可以出于各种原因创建其他线程,但最清楚地说明线程用途的示例是打印。

Let's say you open your favorite word processing application (WPA), type a few lines, and then want to print those lines. If your WPA uses the main thread to print the document, the WPA's user interface will be 'frozen' until the printing is finished. This is because the main thread has to print the lines before it can process any user interface events, i.e., button clicks, mouse movements, etc. It's as if the code were written like this:

假设您打开您最喜欢的文字处理应用程序 (WPA),键入几行,然后想要打印这些行。如果您的 WPA 使用主线程打印文档,则 WPA 的用户界面将“冻结”,直到打印完成。这是因为主线程在处理任何用户界面事件(即按钮点击、鼠标移动等)之前必须打印这些行。 代码就好像是这样写的:

    do
    {
        ProcessUserInterfaceEvents();
        PrintDocument();
    } while (true);

Clearly, this is not what users want. Users want the user interface to be responsive while the document is being printed.

显然,这不是用户想要的。用户希望用户界面在打印文档时能够响应。

The answer, of course, is to print the lines in a second thread. In this way, the user interface can focus on processing user interface events while the secondary thread focuses on printing the lines.

答案当然是在第二个线程中打印这些行。通过这种方式,用户界面可以专注于处理用户界面事件,而辅助线程则专注于打印线条。

The illusion is that both tasks happen simultaneously. On a single processor machine, this cannot be true since the processor can only execute one thread at a time. However, switching between the threads happens so fast that the illusion is usually maintained. On a multi-processor (or mulit-core) machine, this can be literally true since the main thread can run on one processor while the secondary thread runs on another processor.

错觉是这两个任务同时发生。在单处理器机器上,这是不可能的,因为处理器一次只能执行一个线程。然而,线程之间的切换发生得如此之快,以至于通常会保持这种错觉。在多处理器(或多核)机器上,这可能是真的,因为主线程可以在一个处理器上运行,而辅助线程在另一个处理器上运行。

In .NET, threading is a breeze. You can utilize the System.Threading.ThreadPool class, use asynchronous delegates, or create your own System.Threading.Thread objects.

在 .NET 中,线程是轻而易举的。您可以利用 System.Threading.ThreadPool 类,使用异步委托,或创建您自己的 System.Threading.Thread 对象。

If you are new to threading, I would throw out two cautions.

如果你不熟悉线程,我会抛出两个警告。

First, you can actually hurt your application's performance if you choose the wrong threading model. Be careful to avoid using too many threads or trying to thread things that should really happen sequentially.

首先,如果选择错误的线程模型,实际上可能会损害应用程序的性能。小心避免使用太多线程或试图将真正应该顺序发生的事情线程化。

Second (and more importantly), be aware that if you share data between threads, you will likely need to sychronize access to that shared data, e.g., using the lock keyword in C#. There is a wealth of information on this topic available online, so I won't repeat it here. Just be aware that you can run into intermittent, not-always-repeatable bugs if you do not do this carefully.

其次(更重要的是),请注意,如果您在线程之间共享数据,您可能需要同步对共享数据的访问,例如,在 C# 中使用 lock 关键字。网上有很多关于这个主题的信息,所以我不会在这里重复。请注意,如果您不小心执行此操作,您可能会遇到间歇性的、并非总是可重复的错误。