【问题标题】:Hook message loop in Windows Forms application?在 Windows 窗体应用程序中挂钩消息循环?
【发布时间】:2016-04-25 11:53:25
【问题描述】:

我需要在 Windows 窗体应用程序中挂钩消息循环来执行一些与滴答计数相关的工作。

我正在使用异步方法 (async/await) 开发 tcp 服务器,并且避免在多线程进程中处理竞争条件 - 这基本上是我使用 async/await 而不是其他模型的原因.由于这个限制,我不能创建一个后台线程来做滴答计数,因为这样我最终会变成一个多线程代码。

我认为的一个选项是以某种方式连接 Windows 窗体中的消息循环,因此我可以使用我的 Windows 窗体对象的同一线程轻松地完成与滴答计数相关的工作,尽管我没有找到任何合适的方法或 Windows.Forms.Application 类中的事件。

有人知道我需要的方法吗?

谢谢。

【问题讨论】:

  • 异步/等待是多线程...
  • 你好。 @格伦托马斯。我知道 async/await 是多线程的,但是这个模型中的多线程只在较低级别的层中运行。我在 UI 线程中使用 async/await 编写的所有代码都将在 UI 线程中执行。
  • 异步代码不会在 UI 线程中运行
  • 我知道,这就是我的意思......异步代码将在系统的线程池线程中执行,但是当异步代码结束时,它会将执行返回给调用者线程,在我的情况是 UI 线程。
  • 是的,您可以使用任何其他类型的 .NET 线程实现相同的效果

标签: c# winforms


【解决方案1】:

我认为您最好的方法可能是使用计时器,它会按时间间隔执行您的代码:

var aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 5000;
aTimer.Enabled = true;



// What you want to happen when the Elapsed event is raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // Do something
}

【讨论】:

  • 只是补充:如果需要在特定的 SynchronizationContext 中执行 Timer 的回调,请设置 Timer.SynchronizingObject!
【解决方案2】:

您不想覆盖消息循环。在更原始的 GUI 解决方案中,这是一种非常常见的方法,但它实际上是 .NET 上的最后手段。

由于您只需要一个常规的“tick”,因此最合适的解决方案是计时器。既然你想让它在 UI 线程上运行,你应该使用System.Windows.Forms.Timer

【讨论】:

  • 你好斯蒂芬!我最终使用了 System.Timers.Timer,因为我需要在一个没有任何“ui 层”依赖项的程序集中声明这个计时器。我使用的这个计时器也有可能在特定的同步上下文中运行回调。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多