9

在我的 WPF 应用程序中,我想在非 UI 线程中做一些工作,以避免 UI 变得无响应。为此,我这样做了:

var caller = new AsyncMethodCaller<Pattern>(this.SetPatternType);
caller.BeginInvoke(_patterns, null, null);

委托被定义为,

public delegate void AsyncMethodCaller<in T>(IEnumerable<T> data);

我的问题是:

是否BeginInvoke()创建一个新线程并在其中SetPatternType运行回调?如果是这样,这个线程会持续多久?

这种方法一般好吗?如果不是,它有什么问题?我可能面临哪些潜在问题?

我正在使用 C# 4.0 和 Visual Studio 2010。


编辑:

我也需要一些关于这些的指导方针:

我什么时候应该自己创建一个新线程,什么时候应该使用BeginInvoke()?我什么时候应该使用DispatcherObject.Dispatcher.BeginInvoke()对象?

4

3 回答 3

12

从技术上讲,它是not a new thread一个线程池线程,它的持续时间比您的进程/程序长,但可能会立即运行一些其他线程异步调用,它会立即完成您的线程。查看有关异步编程线程池的MSDN 文章以获取完整的详细信息。

并根据您的兴趣检查I/O CompletionPort以获取更多详细信息。

异步编程通常被认为比至少同步代码更好,但是如果您使用 .NET 4.0,请查看Task Parallel Library

基于问题编辑,我什么时候应该创建自己的线程?与创建自己的线程相比,使用 BeginInvoke 或 Async 编程总是更好。当您确定需要一个专用线程连续执行某些任务/工作并且您清楚应用程序中多个线程所需的同步机制时,请严格创建自己的线程。除非您有非常令人信服的理由,否则请尽可能避免创建新线程。您今天添加了一个线程,并且可能继续前进,两年后三个开发人员看到为一些连续的东西添加了一个额外的线程,他们会添加更多等等。相信我,我已经看到了这种情况,因此设置正确的做法(即使用异步方法),人们会尝试遵循这一点。我见过有 150 个线程的应用程序,

刚刚检查了我的东芝笔记本电脑上所有正在运行的进程中是否存在设计不佳的应用程序,东芝蓝牙管理器使用 53 个线程赢得了我的机器上设计最差的程序的桂冠。:)

于 2011-04-07T08:12:47.373 回答
9

它使用线程池 - 因此它不一定会创建一个新线程,但它在与调用线程不同的线程中运行(除非这是一个线程池线程本身,它恰好在安排委托调用之前完成其任务;它不太可能使用相同的线程)。

于 2011-04-07T08:11:31.443 回答
3

Dispatcher.CurrentDispatcher 是 WPF 中的新东西(有点取代 WinForms 中的 InvokeRequired 东西)。

您可以使用 Dispatcher 将您想要的任何更新排队到 GUI,它有不同的优先级可供您选择

看到这个 MSDN 链接

于 2011-04-07T11:17:24.133 回答