Vb.net .NET创建新的调度程序

Vb.net .NET创建新的调度程序,vb.net,multithreading,dispatcher,Vb.net,Multithreading,Dispatcher,我正在尝试使用dispatcher创建第二个线程,这样我就可以让主dispatcher(对于UI)完全没有压力,并且让UI不断响应 现在,我可以为每个子线程创建多个线程(或者在C#中为void),但是我不可能创建一个新线程并获取它的调度程序,然后调用它吗?这就是我所做的: Private CheckLoopThread As New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf CheckLoop)) Ch

我正在尝试使用dispatcher创建第二个线程,这样我就可以让主dispatcher(对于UI)完全没有压力,并且让UI不断响应

现在,我可以为每个子线程创建多个线程(或者在C#中为void),但是我不可能创建一个新线程并获取它的调度程序,然后调用它吗?这就是我所做的:

Private CheckLoopThread As New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf CheckLoop))

CheckLoopThread.Priority = System.Threading.ThreadPriority.Lowest
CheckLoopThread.Start()
Dim Test As Windows.Threading.Dispatcher = Windows.Threading.Dispatcher.FromThread(CheckLoopThread)
但是,变量“Test”在执行“Nothing”之后。这怎么可能?创建第二个调度器的另一种方法是什么

欢迎以任何.NET形式提供答案。Visual Basic或C#。我正在.NET4.0框架上的VB.NETWPF中工作

提前感谢。

不会创建调度程序,如果尚未为线程创建调度程序,则将返回null。要为线程创建调度程序,您必须在
CheckLoopThread
上至少访问一次。正如MSDN上针对
Dispatcher.CurrentDispatcher
所述:

如果调度程序未与当前线程关联,则会生成一个新的 将创建调度程序。FromThread的情况并非如此 方法。如果没有调度程序,FromThread将返回null 与指定的线程关联


我实际上创建了很多这样的调度器,我想正确的方法是按照以下思路:

object theLock = new object();
Dispatcher dispatcher = null;

lock (theLock)
{
    new Thread(new ThreadStart(() =>
    {
        lock (theLock)
        {
            dispatcher = Dispatcher.CurrentDispatcher;
            Monitor.Pulse(theLock);
        }
        Dispatcher.Run();
    })).Start();

    Monitor.Wait(theLock);
}

dispatcher.Invoke(...);
所有的锁定似乎都很复杂,但理论上,
Start()
方法可以在实际设置
dispatcher
之前返回,因此对它的调用可能会导致没有锁的
NullReferenceException

为什么要锁定

我更喜欢:

Dispatcher myDispatcher = null;

ManualResetEvent dispatcherReadyEvent = new ManualResetEvent(false);

new Thread(new ThreadStart(() =>
{
    myDispatcher = Dispatcher.CurrentDispatcher;
    dispatcherReadyEvent.Set();
    Dispatcher.Run();
})).Start();

dispatcherReadyEvent.WaitOne();

myDispatcher.Invoke(...);

确保CheckLoopThread不会在启动后立即结束(如果线程运行的CheckLoop过程执行时间不长)。check循环中有一个循环,它不会结束。非常感谢!确实如此+1.对于使用RedGate的.NET Reflector的用户来说,这是一个重要的注意事项和警告(至少在2021年,从版本10.3.1.1956开始…),对于简单的双线函数
Dispatcher.get_CurrentDispatcher
,该产品显示的C明显不正确。代码错误地声明每次访问
Dispatcher.CurrentDispatcher
属性时都会创建
new Dispatcher()
。但通过切换到产品的IL显示屏,您可以看到情况并非如此。这方面的另一个警告(与我刚才提到的bug无关)是,Microsoft的设计非常混乱。也就是说:
Dispatcher.CurrentDispatcher
是一个(静态)“具有副作用的属性”(boo!),而(静态)方法
Dispatcher.FromThread(…)
——基本上做相同的事情,实际上是非静态的- 副作用。交换这两种语言的语义的设计会更清晰,产生的错误预期也会少得多。这是非常正确的,尽管我不确定底层实现是否相同。老问题,但事实并非如此。Lock在monitor.TryEnter调用周围使用try块。这是为我做的。谢谢