【问题标题】:C# SetPropertyThreadSafe vs Invoke thread-safe callsC# SetPropertyThreadSafe vs Invoke 线程安全调用
【发布时间】:2023-04-01 12:29:01
【问题描述】:

这两种方法中哪一种更适合从另一个线程更新 UI? (对我来说,它们都可以工作,但哪个更安全?) 我更喜欢 SetPropertyThreadSafe 方法,因为它需要的代码更少。

1.

label1.SetPropertyThreadSafe(() => this.label1.Text, "New Value");

2.

if (label1.InvokeRequired)
{
   label1.Invoke(new MethodInvoker(delegate {
   label1.Text="New Value"; }));
}            

【问题讨论】:

  • define better ...否则只是基于意见...
  • 不就是调用invoke的扩展方法吗?它们具有相同级别的“安全性”
  • 他们做的完全一样,所以你应该使用第一个,因为它更漂亮。我们希望我们的代码漂亮,不是吗? :)

标签: c# .net multithreading backgroundworker invoke


【解决方案1】:

SetPropertyThreadSafe 不是 .NET 内置的方法,如果您使用的是this implmentation

public static TResult GetPropertyThreadSafe<TControl, TResult>(this TControl self, Func<TControl, TResult> getter)
    where TControl: Control
{
    if (self.InvokeRequired)
    {
        return (TResult)self.Invoke(getter, self);
    }
    else
    {
        return getter(self);
    }
}

那么你发布的两个例子做的是完全相同的事情,所以没有区别。

【讨论】:

    【解决方案2】:

    如果你去

    1.

    label1.SetPropertyThreadSafe(() => this.label1.Text, "New Value");
    label2.SetPropertyThreadSafe(() => this.label1.Text, "New Value2");
    

    和 2.

    if (label1.InvokeRequired)
    {
       label1.Invoke(new MethodInvoker(delegate 
       {
       label1.Text="New Value"; 
       label2.Text="New Value2"; 
       }));
    }    
    

    那么(2)显然更好,因为它的开销要低得多。但在你的情况下,它们之间没有什么可以选择的。

    如果您知道自己在另一个线程上,则不需要“if InvokeRequired”。

    【讨论】:

    • 您不能只为 label1 调用测试来更新 label2
    • @MarioM,如果您知道它们都在同一个顶级窗口中运行,您可以这样做,因为 WPF 和 WinForms 仅支持每个顶级窗口一个消息队列,因此只能有 1 个 UI 线程每个顶层窗口。
    • 即使您尝试在一个进程中获取多个消息队列也是非常困难的!
    猜你喜欢
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    相关资源
    最近更新 更多