我知道之前已经问过这个问题,但我觉得没有正确询问。
我有一个密集的操作,我希望UI保持响应。我已经阅读了一些帖子,说背景工作者是最好的方法,但是,我认为这假设你有密集任务的源代码。
我有一个我没有源代码的库,我可以检查进度的唯一方法是附加到被触发的事件并获取信息。
我在MSDN网站上看到的例子假设有一个来源。
我知道如何通过附加到事件来获得进度(这是一个百分比值),但是如何将该值返回到UI?
答案 0 :(得分:2)
以下答案基于我的直觉,并没有真正用第三方库进行测试。
在事件中,处理程序代码应如下所示:
private void EventHandler(object sender, DirtyEventArgs e)
{
if (myControl.InvokeRequired)
myControl.Invoke(new MethodInvoker(MethodToUpdateUI), e);
else
MethodToUpdateUI(e);
}
private void MethodToUpdateUI(object obj)
{
// Update UI
}
答案 1 :(得分:1)
附加到第三方组件中的进度事件,并在BackgroundWorker
上致电ReportProgress
。让您的UI附加到BackgroundWorker.ProgressChanged
事件以更新UI。
答案 2 :(得分:0)
通过使用第二个线程和线程安全队列,您可以获得所需的效果。
您可以创建一个侦听事件的第二个线程。 当新事件发生时,它会将事件信息推送到队列(线程安全同步)。
使用定时器(Windows.Forms.Timer)每隔x次检查一次该队列,如果存在新事件,可以更新UI。
因为计时器在主线程中运行,所以它可以安全地更新UI,如果你重量轻,它就不会阻塞它足够长的时间以便被注意到。
答案 3 :(得分:0)
关于this Q的类似讨论。如果您出于某种原因无法或不想使用BackgroundWorker,您可以使用自己的线程并将事件中的事件编组回UI线程。
private void Initialise() {
MyLibClass myLibClass = new MyLibClass();
myLibClass.SomeEvent += SomeEventHandler;
ThreadPool.QueueUserWorkItem(myLibClass.StartLongTask);
}
private void SomeEventHandler(EventArgs e) {
if (this.Dispatcher.Thread != Thread.CurrentThread) {
this.Dispatcher.Invoke(delegate { DoStuffOnUIThread(e); });
}
else {
DoStuffOnUIThread(e);
}
}