从后台线程更新 UI

发布于 2024-12-13 03:27:45 字数 614 浏览 1 评论 0原文

这只是一个好奇的问题。哪一种是从另一个线程更新 UI 的最佳方法。首先,这个:

private delegate void MyDelegateMethod();
void MyMethod()
{
    if (unknowncontrol.InvokeRequired)
    {
        this.BeginInvoke(new MyDelegateMethod(MyMethod));
        return;
    }
    unknowncontrol.property = "updating!";
}

另一方面:

Invoke((System.Threading.ThreadStart)delegate()
{
    unknowncontrol.property = "updating!";
});

或者,有更好的方法吗?

当然这是针对 WinForms 的,对于 WPF 则有调度程序。 WPF的代码是怎样的?

我问的是,因为过去我在使用上述两个选项从引发的事件更新 UI 时遇到了错误。类似这样的错误:“没有可用的源代码”。我想我们所有人都见过它们:D。

谢谢,祝你有美好的一天!

This is just a curious question. Which one is the best way to update UI from another thread. First, this one:

private delegate void MyDelegateMethod();
void MyMethod()
{
    if (unknowncontrol.InvokeRequired)
    {
        this.BeginInvoke(new MyDelegateMethod(MyMethod));
        return;
    }
    unknowncontrol.property = "updating!";
}

On the other hand:

Invoke((System.Threading.ThreadStart)delegate()
{
    unknowncontrol.property = "updating!";
});

Or, is there a better way to do this?

Of course this is for WinForms, for WPF there's the dispatcher. How is the code for WPF?

I'm asking, 'cause, in the past I experienced errors when updating UI from a raised event using both of the options above. The kind of error like: "there is no source code available". I assume all of us have seen them :D.

Thanks, and have a nice day!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

尘世孤行 2024-12-20 03:27:45

查看 Roy Osherove 的博客文章:http://osherove.com/blog/2006/3/1/the-3-ways-to-create-a-thread-safe-gui-with-net-20-with-one。 html

delegate void Func<T>(T t);
Func del = delegate
{

  // UI Code goes here
};
Invoke(del);

Check out Roy Osherove's blog post on this: http://osherove.com/blog/2006/3/1/the-3-ways-to-create-a-thread-safe-gui-with-net-20-with-one.html

delegate void Func<T>(T t);
Func del = delegate
{

  // UI Code goes here
};
Invoke(del);
寄风 2024-12-20 03:27:45

我通常使用第一个模型,但这只是因为我发现它更清晰。两者之间实际上并不存在有效的区别。

I typically used the first model, but that's only because I found it clearer. There isn't really going to be an effective difference between the two.

童话 2024-12-20 03:27:45

我认为最好的方法是设置 ui 元素的属性绑定到的 CLR 属性。

As i see it the best way is to set a CLR-property to which the ui-element's property is bound to.

初与友歌 2024-12-20 03:27:45

第一个方法 (BeginInvoke) 确保 UI 更新代码在创建控件的同一线程上执行。第二种方法则不然。让所有 UI 更新代码在同一线程上执行可以避免大量线程问题,并允许您使用不一定是线程安全的控件。

The first method (BeginInvoke) ensures that the UI update code executes on the same thread that created the control. The 2nd method does not. Having all UI updating code execute on the same thread avoids alot of threading issues and allows you to use controls that are not necessarily thread-safe.

败给现实 2024-12-20 03:27:45

默认的 Action delegate 在 90% 的时间内都可以工作:

private void Log(String value)
{
    // Verify that we're on the same thread
    if (textBox1.InvokeRequired)
    {
        // We're not on the same thread - Invoke the UI thread
        textBox1.Invoke(new Action<string>(Log), value);
        return;
    }

    // We're on the same thread - Update UI
    textBox1.Text += value + "\r\n";
}

private void OnSomethingHappened()
{
    Log("Something happened!");
}

The default Action delegate worked 90% of the time:

private void Log(String value)
{
    // Verify that we're on the same thread
    if (textBox1.InvokeRequired)
    {
        // We're not on the same thread - Invoke the UI thread
        textBox1.Invoke(new Action<string>(Log), value);
        return;
    }

    // We're on the same thread - Update UI
    textBox1.Text += value + "\r\n";
}

private void OnSomethingHappened()
{
    Log("Something happened!");
}
江城子 2024-12-20 03:27:45

使用 [Dispatcher.Invoke(DispatcherPriority, Delegate)]< /a> 从另一个线程或后台更改 UI。

第 1 步。使用以下命名空间

using System.Windows;
using System.Threading;
using System.Windows.Threading;

第 2 步。将以下行放在需要更新 UI 的位置

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate
{
    //Update UI here
}));

语法

<前><代码>[BrowsableAttribute(假)]
公共对象调用(
DispatcherPriority优先,
委托方式

参数

优先级

类型:System.Windows.Threading.DispatcherPriority

相对于其他待处理操作的优先级
Dispatcher事件队列,指定方法被调用。

方法

类型:System.Delegate

不带参数的方法的委托,该方法被推送到
调度程序事件队列。

返回值

类型:System.Object

被调用的委托的返回值,如果
delegate没有返回值。

版本信息

自 .NET Framework 3.0 起可用

Use [Dispatcher.Invoke(DispatcherPriority, Delegate)] to change the UI from another thread or from background.

Step 1. Use the following namespaces

using System.Windows;
using System.Threading;
using System.Windows.Threading;

Step 2. Put the following line where you need to update UI

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate
{
    //Update UI here
}));

Syntax

[BrowsableAttribute(false)]
public object Invoke(
  DispatcherPriority priority,
  Delegate method
)

Parameters

priority

Type: System.Windows.Threading.DispatcherPriority

The priority, relative to the other pending operations in the
Dispatcher event queue, the specified method is invoked.

method

Type: System.Delegate

A delegate to a method that takes no arguments, which is pushed onto
the Dispatcher event queue.

Return Value

Type: System.Object

The return value from the delegate being invoked or null if the
delegate has no return value.

Version Information

Available since .NET Framework 3.0

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文