winform框架中的调度器

UI框架的调度器(也称为消息循环或事件循环)

在 C# 中,UI 对象通常是由 UI 线程创建和管理的,这是因为 UI 对象通常与图形化界面相关,需要与用户交互和更新界面。UI 线程是一个特殊的线程,负责处理 UI 相关的操作,例如绘制界面、处理用户输入等。

非后台线程是在后台执行的线程,它们通常用于执行一些耗时的操作,例如计算、网络请求等。这些操作可能会阻塞线程,导致界面失去响应或出现卡顿。

为了保证界面的稳定性和响应性,C# 中的 UI 对象通常只能在所属的 UI 线程中被访问。这是因为 UI 对象在创建时与 UI 线程相关联,并且 UI 线程对其进行了同步和更新操作。如果从非后台线程访问 UI 对象,可能会引发线程冲突、界面更新冲突等问题,导致程序崩溃或出现意外的行为。

要在非后台线程中访问 UI 对象,可以使用 Invoke BeginInvoke 方法来将操作发送到 UI 线程执行。这些方法使得 UI 对象能够通过委托在 UI 线程上执行,确保线程安全和正确的界面更新。

// 在非后台线程中访问 UI 对象的示例
void SomeLongOperation()
{
    // 执行耗时操作
    // 需要在 UI 线程中更新界面时,使用 Invoke 或 BeginInvoke
    uiElement.Dispatcher.Invoke(() =>
    {
        // 在 UI 线程中执行界面更新操作
    });
}

综上所述,由于线程安全和界面稳定性的原因,UI 对象通常只能在所属的 UI 线程中被访问,非后台线程需要通过 Invoke 或 BeginInvoke 方法来与 UI 线程进行交互。

后台线程之间互相访问对象

后台线程之间访问不会出现线程冲突

public void Dd()
{
    Thread t = new Thread(() =>
    {
        Message message = new Message();
        Thread thread = new Thread(() =>
        {
            while (true)
            {
                message.Count++;
                Console.WriteLine(message.Count.ToString());
                Thread.Sleep(500);
            }
        });
        thread.Start();
    });
    t.Start();
}
public class Message
{
    public int Count { get; set; }
}

Dispatcher

Dispatcher 是一个用于执行操作的线程调度器。在 WPF 和 UWP 应用程序中,每个 UI 线程都拥有一个关联的 Dispatcher 对象。Dispatcher 提供了一个队列,用于存储将在 UI 线程上执行的操作。

Dispatcher 的主要作用是确保操作在 UI 线程上执行,以确保线程安全和正确的界面更新。当后台线程需要访问或更新 UI 对象时,可以使用 Dispatcher 的 Invoke 或 BeginInvoke 方法将操作封装在一个委托中,然后将其发送到 UI 线程上执行。这样,操作将由 UI 线程执行,避免了线程冲突和界面更新冲突。

在 WPF 中,可以通过 Application.Current.Dispatcher 属性来访问主线程的 Dispatcher 对象。在 UWP 中,可以通过 CoreDispatcher 对象来访问 Dispatcher。无论在哪种平台上,Dispatcher 都提供了类似的方法和功能,用于执行操作和处理 UI 线程上的事件。

例如,下面是使用 Dispatcher 在后台线程中访问 UI 对象的示例:

void BackgroundThreadOperation()
{
    // 执行后台线程操作
    // 使用 Dispatcher 将操作发送到 UI 线程上执行
    Application.Current.Dispatcher.Invoke(() =>
    {
        // 在 UI 线程中执行界面更新操作
    });
}

总之,Dispatcher 是用于执行操作的线程调度器,可以确保操作在 UI 线程上执行,从而实现线程安全和正确的界面更新。在后台线程访问 UI 对象时,建议使用 Dispatcher 的 Invoke 或 BeginInvoke 方法来操作 UI 线程。

Dev中的Dispatch

DevExpress中的IDispatcherService是一个接口,用于在非UI线程中调度对UI线程的操作。通常在后台任务中需要更新UI时使用。

在DevExpress中,可以通过以下方式获取IDispatcherService实例:

通过DXMessageBoxService类的DispatcherService属性:

IDispatcherService dispatcherService = DXMessageBoxService.DispatcherService;

通过DXSplashScreen类的DispatcherService属性:

IDispatcherService dispatcherService = DXSplashScreen.DispatcherService;

一旦获取到了IDispatcherService实例,就可以使用其提供的Invoke、BeginInvoke等方法来调度对UI线程的操作。

例如:

dispatcherService.BeginInvoke(() =>
{
    // 在UI线程中执行的操作
});

需要注意的是,在使用IDispatcherService调度UI操作时,需要确保当前的执行上下文是UI线程上下文,否则可能会引发异常。

posted @ 2023-09-16 11:15  回首起了风沙  Views(34)  Comments(0Edit  收藏  举报