1

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

我将对 SetWindowPos 的调用放入辅助 System.Thread,但它仍然被阻止。看来 SetWindowPos 总是由拥有该窗口的线程处理。因此,如果我的主线程很忙,即使请求是从不同的线程发送的,也无法移动窗口。

即使拥有窗口的线程很忙,是否还有其他方法可以移动窗口?谢谢!

4

1 回答 1

2

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

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

同样,如果您的 UI 线程代码中的某处有Thread.Sleep(),那么 UI 也会在同一时间段内冻结。

备择方案

您可能需要考虑将冗长的操作移至另一个线程,或者采用简单的当代和推荐方式并使用async/await. 这样做可以让您在阻塞 UI 的情况下执行冗长的操作。

计时器

此外,请考虑使用 aTimer代替Thread.Sleep()或等效项作为每秒移动窗口 100 次的替代方法。请务必为 GUI 应用程序使用正确的计时器,因为 .NET 定义了至少四 (4) 个我相信并且默认情况下(如果有的话)并非所有适合GUI 应用程序

于 2019-03-24T01:50:59.033 回答