gpt4 book ai didi

c# - 从线程调用 Invoke/BeginInvoke

转载 作者:行者123 更新时间:2023-11-30 12:17:03 24 4
gpt4 key购买 nike

我有一个 C# 2.0 应用程序,其表单使用包含线程的类。

在线程函数中,不是直接调用事件处理程序,而是调用它。效果是拥有窗体不需要调用 InvokeRequired/BeginInvoke 来更新其控件。

public class Foo
{
private Control owner_;
Thread thread_;

public event EventHandler<EventArgs> FooEvent;

public Foo(Control owner)
{
owner_ = owner;
thread_ = new Thread(FooThread);
thread_.Start();
}

private void FooThread()
{
Thread.Sleep(1000);
for (;;)
{
// Invoke performed in the thread
owner_.Invoke((EventHandler<EventArgs>)InternalFooEvent,
new object[] { this, new EventArgs() });
Thread.Sleep(10);
}
}

private void InternalFooEvent(object sender, EventArgs e)
{
EventHandler<EventArgs> evt = FooEvent;
if (evt != null)
evt(sender, e);
}
}

public partial class Form1 : Form
{
private Foo foo_;

public Form1()
{
InitializeComponent();

foo_ = new Foo(this);
foo_.FooEvent += OnFooEvent;
}

private void OnFooEvent(object sender, EventArgs e)
{
// does not need to call InvokeRequired/BeginInvoke()
label_.Text = "hello";
}
}

这显然与 System.Timers.Timer 和 System.Io.Ports.SerialPort 等使用后台线程的 Microsoft API 使用的方法相反。这种方法有什么本质上的错误吗?它在某种程度上是危险的吗?

谢谢, 保罗H


编辑:另外,如果表单没有立即订阅事件怎么办?它会用表单不感兴趣的事件阻塞表单的消息队列吗?

最佳答案

这是一个线程安全的调用,该方法将在表单的线程中处理。

从概念上看没有错。

不过,计时器对于此类任务更为优雅。但是,间隔为 10 毫秒的计时器可能会减慢 GUI,这可能就是使用 Invoke 的原因。

您不需要调用 InvokeRequired,因为很明显控件在另一个线程中。此外,只有在您想异步调用方法时才需要调用 BeginInvoke,显然这里不是这种情况。

关于您的编辑:不会,消息队列不会被阻塞。如果没有注册处理程序,则不会触发任何事件。再看看你的代码 ;)

关于c# - 从线程调用 Invoke/BeginInvoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4327566/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com