相关疑难解决方法(0)

检测是否在WPF和Winforms中的UI线程上

我在下面编写了一个断言方法Ensure.CurrentlyOnUiThread(),用于检查当前线程是否为UI线程.

  • 这在检测Winforms UI线程时是否可靠?
  • 我们的应用程序是混合WPF和Winforms,如何最好地检测有效的WPF UI线程?
  • 有一个更好的方法吗?也许代码合同?

Ensure.cs

using System.Diagnostics;
using System.Windows.Forms;

public static class Ensure
{
    [Conditional("DEBUG")]
    public static void CurrentlyOnUiThread()
    {
        if (!Application.MessageLoop)
        {
            throw new ThreadStateException("Assertion failed: not on the UI thread");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c# wpf assertions winforms

42
推荐指数
5
解决办法
4万
查看次数

WPF中的Dispatcher to Thread关系

我不完全清楚应用程序中有多少Dispatchers以及它们与Threads相关或引用的方式.

据我所知,WPF应用程序有2个线程(一个用于输入,另一个用于UI)和1个调度程序(与UI-Thread相关联).如果我创建另一个线程 - 让我们称之为"工作线程" - 当我调用Dispatcher.CurrentDispatcher工作线程时,我会得到哪个调度程序怎么办?

另一种情况:假设一个带有2个线程的控制台应用程序 - 主线程和输入线程.在主线程上,我首先创建输入线程,然后我调用Application.Run()

Thread thread = new Thread(new ThreadStart(UserInputThreadFunction));
thread.Start();
Application.Run();
Run Code Online (Sandbox Code Playgroud)

会有一个调度员,对吗?在输入线程上,Dispatcher.CurrentDispatcher是否返回主线程的调度程序?或者将实例提供给主线程调度程序的正确方法是什么?

可能是WPF应用程序中有多个调度程序吗?有没有,创建另一个调度员是有意义的吗?

.net c# wpf dispatcher

24
推荐指数
2
解决办法
2万
查看次数

在另一个线程中运行WPF控件

我在我的项目中使用了一个可视化控件,它来自一个我没有源代码的库.
更新(大约200ms)以获得良好的UI响应时间需要很长时间,其中三个控件同时在屏幕上显示.(我可能需要一次更新所有三个,这使得我的UI在他们都在思考的时候停留了大约600毫秒).

我已经阅读了一些关于TaskSchedulers的帖子,并开始研究并行任务功能,作为在自己的线程中运行每个控件的一种方式.该平台将是多核的,所以我想利用同步处理.

问题是我甚至不知道我不知道如何解决这个问题.

是否有合适的设计模式用于在WPF中的主UI线程的单独线程中运行控件?

具体来说:它是第三方地图控件,当给定新位置或缩放级别时需要太长时间才能重绘(~200ms).可能有三个更新最多4Hz - 显然它们不会跟上..
我已经在用户控件中封装了WPF控件,并且需要在它自己的线程中运行每个实例,同时仍然捕获用户输入(鼠标点击, 例如).

更新:虽然我正在寻找解决方案,但到目前为止我已实施了以下内容.
我的主(UI)线程产生一个线程,该线程创建一个包含相关控件的新窗口,并将其定位在正确的位置(这样它看起来只是一个普通的控件).

_leftTopThread = new Thread(() =>
{
   _topLeftMap = new MapWindow()
   {
      WindowStartupLocation = WindowStartupLocation.Manual,
      Width = leftLocation.Width,
      Height = leftLocation.Height,
      Left = leftLocation.X,
      Top = leftLocation.Y,
      CommandQueue = _leftMapCommandQueue,
   };

   _topLeftMap.Show();
   System.Windows.Threading.Dispatcher.Run();

});

_leftTopThread.SetApartmentState(ApartmentState.STA);
_leftTopThread.IsBackground = true;
_leftTopThread.Name = "LeftTop";
_leftTopThread.Start();
Run Code Online (Sandbox Code Playgroud)

哪个CommandQueue线程安全的BlockingCollection队列,用于向地图发送命令(移动位置等).
现在的问题是,我可以

  • System.Windows.Threading.Dispatcher.Run()呼叫而有用户输入
  • 或阻塞CommandQueue,侦听主线程发送的命令

我无法等待命令,因为它会吸收我所有的线程CPU!
是否有可能阻止有事件消息泵的工作?

c# wpf multithreading blocking task-parallel-library

18
推荐指数
2
解决办法
1万
查看次数