获取EventHandler在原始线程上调用Invoke()



我正在使用System.Threading.Timer异步重复某个任务。当任务准备好时,应该在原始线程(Start()被调用的地方)上执行一个方法。

public event EventHandler StatusChanged;
public void Start()
{
StatusChanged += new EventHandler(SomethingChangedMethod);
new Timer(Pending, null, 0, 1000);
}
private void Pending(object state)
{
//Do Something
StatusChanged?.Invoke(this, EventArgs.Empty);
}

由于我不是在控制或什么的,我不能调用Invoke()BeginInvoke()

由于Start()可以从库外调用,因此我对此没有真正的控制。

作为库的作者,你不知道该做什么。正如你所知道的那样,原来的线程在很久以前就开始调用Start并退出了。你不知道回到"相同的"thread"是正确的行为,所以当然,是的,你把它留给你的消费者。

同样的,作为一个库的作者,你不应该选择使用什么日志框架,如果&如何向用户显示错误消息(如果有用户的话),等等。

做简单的事情,引发事件,让为应用程序选择框架的人做出正确的选择。因为您不应该(在不损害库的潜在消费者的情况下)

首先,您可能会或可能不会向调用Start的线程发布消息:只有当线程具有与之关联的消息队列并且正在检查该队列时,您才能这样做。UI线程可以这样做,但是例如线程池线程,或者你用new Thread()创建的线程,就不会。

如果一个线程有一个与之关联的消息队列,通常的做法是在该线程上安装一个SynchronizationContext。您可以使用SynchronizationContext.Current获取线程的SynchronizationContext,将其存储起来,然后使用该SynchronizationContext将消息发布到该线程的消息队列。如果一个线程没有安装SynchronizationContext,则SynchronizationContext.Current返回null

public event EventHandler StatusChanged;
private Timer timer;
private SynchronizationContext synchronizationContext;
public void Start()
{
synchronizationContext = SynchronizationContext.Current;
StatusChanged += new EventHandler(SomethingChangedMethod);
timer = new Timer(Pending, null, 0, 1000);
}
private void Pending(object state)
{
// Do Something
if (synchronizationContext != null)
{
synchronizationContext.Post(_ => StatusChanged?.Invoke(this, EventArgs.Empty), null);
} 
else
{
StatusChanged?.Invoke(this, EventArgs.Empty);
}
}

最新更新