- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在编写一个 API 来促进与串行端口的通信。我正在进行一些重构和一般清理,想知道是否有办法避免以下问题。
API 中的主类能够不断从端口读取数据,并在读取字节与特定正则表达式匹配时引发包含值的事件。读取和解析的过程发生在另一个线程上。该事件包含作为参数 (string
) 的值,并且因为它是从另一个线程引发的,所以客户端试图直接将值分配给 除非处理程序具有正确的
属性会导致跨线程异常。Invoke
代码,否则控件的 Text
我理解为什么会发生这种情况,当我将正确的调用代码放入测试客户端的事件处理程序时,一切都很好;我的问题是我是否可以在 API 代码本身中做任何事情,以便客户不必担心它。
基本上,我想把这个:
void PortAdapter_ValueChanged(Command command, string value)
{
if (this.InvokeRequired)
{
Invoke(new MethodInvoker(() =>
{
receivedTextBox.Text = value;
}));
}
else
{
receivedTextBox.Text = value;
}
}
简单地说:
void PortAdapter_ValueChanged(Command command, string value)
{
receivedTextBox.Text = value;
}
最佳答案
嗯,在 .Net 框架本身的许多地方使用了一个通用模式。例如 BackgroundWorker
使用此模型。
为此,您将使用 SynchronizationContext
作为 API 的参数,在本例中我假设它是 PortAdapter
。
引发事件时,您可以使用 SynchronizationContext.Post
或 SynchronizationContext.Send
在给定的 SynchronizationContext
中引发事件。前者是异步的,后者是同步的。
因此,当客户端代码创建您的 PortAdapter
实例时,它会将 WindowsFormsSynchronizationContext
实例作为参数传递。这意味着 PortAdapter
将在给定的同步上下文中引发事件,这也意味着您不需要 InvokeRequired
或 Invoke
调用。
public class PortAdapter
{
public event EventHandler SomethingHappened;
private readonly SynchronizationContext context;
public PortAdapter(SynchronizationContext context)
{
this.context = context ?? new SynchronizationContext();//If no context use thread pool
}
private void DoSomethingInteresting()
{
//Do something
EventHandler handler = SomethingHappened;
if (handler != null)
{
//Raise the event in client's context so that client doesn't needs Invoke
context.Post(x => handler(this, EventArgs.Empty), null);
}
}
}
客户端代码:
PortAdapter adpater = new PortAdapter(SynchronizationContext.Current);
...
在 UI 线程中创建 PortAdapter
的实例非常重要,否则 SynchronizationContext.Current
将为 null,因此事件仍将在 ThreadPool 线程中引发。
关于c# - 防止事件处理程序中 InvokeRequired 的必要性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26343132/
所以我有这个棋盘,可以玩棋盘游戏...问题是,我怎么知道用户点击了哪个方 block ?我知道 x 和 y 坐标,但我该如何自动化它,而不需要寻找每个方 block 的具体位置。 (而且棋盘的大小是可
我是一名优秀的程序员,十分优秀!