SetWindowPos即使在主线程被阻塞时?

时间:2019-03-24 01:35:46

标签: c# multithreading setwindowpos

我试图通过每隔10毫秒调用SetWindowPos来使程序移动,以跟随光标。问题是,当我的程序的主线程被Thread.Sleep()阻塞时,窗口停止移动。

我将对SetWindowPos的调用放入了辅助System.Thread中,但仍被阻止。似乎SetWindowPos总是由拥有窗口的线程处理。因此,即使我的主线程很忙,即使请求是从其他线程发送的,也无法移动窗口。

即使拥有该窗口的线程很忙,是否存在另一种移动窗口的方法?谢谢!

1 个答案:

答案 0 :(得分:2)

我不这么认为。所有UI操作必须必须在主应用程序线程(在GUI应用程序中称为 UI线程)上执行。是否为 button点击事件;鼠标移动滚动;绘画等(包括移动窗口),这些操作在应用程序消息队列(类似于Windows为所有应用程序维护的FIFO缓冲区)中排队,必须由UI线程处理。

如果说一个按钮单击事件需要很长时间,因为程序员决定在与回调相同的线程中执行冗长的数据库操作,则UI将冻结,直到回调完成为止,而该回调恰好是数据库代码。 / p>

类似地,如果您的UI线程代码中的某个位置有一个Thread.Sleep(),则UI也将在同一时期冻结。

替代品

您可能要考虑将冗长的操作移至另一个线程,采用简单的当代建议方法并使用async/await。这样做使您可以执行长时间的操作而不会阻塞UI。

计时器

此外,考虑使用Timer而不是Thread.Sleep()或等效语言来代替每秒移动窗口100次。确保为GUI应用程序使用正确的计时器,因为.NET默认定义了至少四(4)个,我相信且并非所有合适 (如果有的话) GUI应用