在我的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()
对象?
答案 0 :(得分:11)
技术上not a new thread
是一个Threadpool线程,它的上传时间比你的进程/程序长,但可能会运行一些其他线程异步调用,它会立即完成你的。查看Asynch Programming和Threadpool上的MSDN文章以获取完整的详细信息。
根据您的兴趣检查I/O CompletionPort了解更多详情。
Asynch编程通常被认为比至少同步代码更好,但如果您使用的是.NET 4.0,请查看Task Parallel Library。
根据问题编辑,我应该何时创建自己的主题? 与创建自己的线程相比,使用BeginInvoke或Async编程总是更好。当您确定需要专用线程连续执行某项任务/工作并且您清楚应用程序中多个线程所需的同步机制时,严格创建自己的线程。除非你有一个非常令人信服的理由,否则尽可能避免创建新线程。你今天添加一个线程,可能继续前进,两年后,三个开发人员看到为一些连续的东西添加了一个额外的线程,他们将添加更多等等。相信我,我已经看到了这种情况,因此设置了正确的做法(即使用Asynch方法),人们将尝试遵循这一点。我见过有150个线程的应用程序,这在双核或四核机器上是否有意义,我不这么认为。
刚刚检查了我的东芝笔记本电脑上的所有正在运行的进程,这些设计糟糕的应用程序,东芝蓝牙管理器使用53个线程赢得了我的盒子上设计最差的程序的王冠。 :)
答案 1 :(得分:8)
它使用线程池 - 因此它不一定会创建一个新线程,但它在与调用线程不同的线程中运行(除非那是一个线程池线程本身,它恰好完成在调度委托调用之前的任务;它不太可能使用相同的线程。)
答案 2 :(得分:3)
Dispatcher.CurrentDispatcher是WPF中的新东西(在WinForms中替换了InvokeRequired的东西)。
您可以使用Dispatcher将所需的任何更新排入GUI,并且可以选择不同的优先级