C# 是否有任何方法可以在非WPF线程上使用Dispatcher;多线程的新特性

C# 是否有任何方法可以在非WPF线程上使用Dispatcher;多线程的新特性,c#,dispatcher,C#,Dispatcher,为什么这不起作用 我想做的是: 我需要一种在特定线程中运行特定方法的方法,该线程一直运行到程序结束 我的其他可能选择: 据我所知,一种可能的方法是实现一个队列。我可以将希望在特定线程中运行的方法推入其中。在特定线程中,我将旋转并休眠/monitor.pulse,以查看队列中是否有代理等待运行 我的目标: 是为了避免所有创建代理队列、维护锁等的繁重工作。似乎WPF世界中存在一个名为Dispatcher的现成解决方案。WPF控件大多继承自DispatcherObject,并且以某种方式使整个过程正常

为什么这不起作用

我想做的是: 我需要一种在特定线程中运行特定方法的方法,该线程一直运行到程序结束

我的其他可能选择: 据我所知,一种可能的方法是实现一个队列。我可以将希望在特定线程中运行的方法推入其中。在特定线程中,我将旋转并休眠/monitor.pulse,以查看队列中是否有代理等待运行

我的目标: 是为了避免所有创建代理队列、维护锁等的繁重工作。似乎WPF世界中存在一个名为Dispatcher的现成解决方案。WPF控件大多继承自DispatcherObject,并且以某种方式使整个过程正常工作。我要怎么做才能得到这份工作

using System;
using System.Threading;
using System.Windows.Threading;

namespace ThreadingTrials
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "mainThread";
            Engine engine = new Engine();
            Console.WriteLine("initializing SpecialEngine from {0}", Thread.CurrentThread.Name);
            engine.initialize();
            engine.doWork();
        }
    }
    class Engine:DispatcherObject
    {
        private EventWaitHandle InitializationComplete;
        private EventWaitHandle newWorkComplete;
        //private Dispatcher dispatcher;
        public Engine()
        {

        }
        public void initialize()
        {
            InitializationComplete = new EventWaitHandle(false, EventResetMode.ManualReset);
            Thread thread = new Thread(new ParameterizedThreadStart((hwnd)=>
            {
                InitializeSpecialEngineObject();
                while (true) ;
            }));
            thread.Name = "Special Engine Thread";

            thread.SetApartmentState(ApartmentState.STA);
            thread.Priority = ThreadPriority.Normal;
            thread.Start();
            Console.WriteLine("waiting for initialize at {0}", Thread.CurrentThread.Name);
            InitializationComplete.WaitOne();
        }
        private void InitializeSpecialEngineObject()
        {
            Console.WriteLine("doing initialization at {0}", Thread.CurrentThread.Name);
            Thread.Sleep(500);
            //dispatcher = Dispatcher.CurrentDispatcher;
            InitializationComplete.Set();
        }

        internal void doWork()
        {
            newWorkComplete = new EventWaitHandle(false, EventResetMode.AutoReset);
            //Dispatcher.Thread.Suspend();
            Dispatcher.Invoke((SendOrPostCallback)delegate
                {
                    Console.WriteLine("dispatched to {0}", Thread.CurrentThread.Name);
                    Thread.Sleep(500);
                    newWorkComplete.Set();
                },DispatcherPriority.Background, null);
            Dispatcher.Thread.Resume();
            Console.WriteLine("waiting for new work to complete at {0}", Thread.CurrentThread.Name);
            newWorkComplete.WaitOne();
        }
        private void doingWork()
        {
            Console.WriteLine("Doing work in {0}", Thread.CurrentThread.Name);

            Thread.Sleep(500);
        }
    }
}
谢谢你的意见。 很公平。实际上,制作一个简单的工作线程来等待表示void()委托队列中的新任务的事件,并在它们可用时运行它们,所做的工作非常少。我从网上复制了大部分代码。。。对不起,丢失了参考资料。我是在那天做的,应该早点编辑这篇文章

using System;
using System.Threading;
using System.Collections.Generic;

class ProducerConsumerQueue : IDisposable
{
    EventWaitHandle _wh = new AutoResetEvent(false);
    Thread _worker;
    readonly object _locker = new object();
    Queue<Action> _tasks = new Queue<Action>();

    public delegate void Action();

    public ProducerConsumerQueue()
    {
        _worker = new Thread(Work);
        _worker.Start();
    }

    public void EnqueueTask(Action work)
    {
        lock (_locker) _tasks.Enqueue(work);
        _wh.Set();
    }

    public void Dispose()
    {
        EnqueueTask(null);     // Signal the consumer to exit.
        _worker.Join();         // Wait for the consumer's thread to finish.
        _wh.Close();            // Release any OS resources.
    }

    void Work()
    {
        while (true)
        {
            Action task = null;
            lock (_locker)
                if (_tasks.Count > 0)
                {
                    task = _tasks.Dequeue();
                    if (task == null) return;
                }
            if (task != null)
            {
                task.Invoke();
            }
            else
                _wh.WaitOne();         // No more tasks - wait for a signal
        }
    }

}
class Program
{
    static void Main()
    {
        using (ProducerConsumerQueue q = new ProducerConsumerQueue())
        {
            q.EnqueueTask(delegate 
            {
                Console.WriteLine("Performing task: Hello");
                Thread.Sleep(1000);  // simulate work...
            });
            for (int i = 0; i < 10; i++) q.EnqueueTask(delegate 
            {
                Console.WriteLine("Performing task: "+ i);
                Thread.Sleep(1000);  // simulate work...
            });
            q.EnqueueTask(delegate 
            {
                Console.WriteLine("Performing task: Goodbye!");
                Thread.Sleep(1000);  // simulate work...
            });
        }

        // Exiting the using statement calls q's Dispose method, which
        // enqueues a null task and waits until the consumer finishes.
    }
}
使用系统;
使用系统线程;
使用System.Collections.Generic;
类ProducerConsumerQueue:IDisposable
{
EventWaitHandle_wh=新的自动存储事件(false);
螺纹工;
只读对象_locker=新对象();
队列_tasks=新队列();
公共委托无效操作();
公共产品消费者队列()
{
_工人=新线程(工作);
_worker.Start();
}
公共void排队任务(操作工作)
{
锁定(_locker)_任务。排队(工作);
_wh.Set();
}
公共空间处置()
{
EnqueueTask(null);//通知使用者退出。
_worker.Join();//等待使用者的线程完成。
_wh.Close();//释放所有操作系统资源。
}
无效工作()
{
while(true)
{
动作任务=null;
锁(储物柜)
如果(_tasks.Count>0)
{
task=_tasks.Dequeue();
if(task==null)返回;
}
如果(任务!=null)
{
task.Invoke();
}
其他的
_wh.WaitOne();//不再有任务-等待信号
}
}
}
班级计划
{
静态void Main()
{
使用(ProducerConsumerQueue q=new ProducerConsumerQueue())
{
q、 排队任务(委托)
{
Console.WriteLine(“正在执行任务:Hello”);
Thread.Sleep(1000);//模拟工作。。。
});
对于(int i=0;i<10;i++)q.EnqueueTask(委托
{
Console.WriteLine(“执行任务:+i”);
Thread.Sleep(1000);//模拟工作。。。
});
q、 排队任务(委托)
{
控制台.WriteLine(“正在执行任务:再见!”);
Thread.Sleep(1000);//模拟工作。。。
});
}
//退出using语句调用q的Dispose方法,该方法
//将空任务排入队列并等待使用者完成。
}
}

您不能调用
调度程序。请运行
。您假设一个
调度程序
包含一个执行其工作的
线程
,但这是反向的。第一次调用
Dispatcher.CurrentDispatcher
时,将创建绑定到当前线程的
Dispatcher
。请注意,即使您的代码不直接调用
CurrentDispatcher
,它也会通过构造
DispatcherObject
(将
CurrentDispatcher
捕获到字段中)间接调用

查看,其中包含所需的所有详细信息

如果您希望在子线程中使用类似dispatcher的功能,但不希望依赖WPF,则可以使用中的
ActionThread
类,这大致相当于一个
dispatcher
加上一个专用的
thread

重复我发出的警告,微软最初的API设计导致了错误的预期;而
调度器。​CurrentDispatcher
是一个有副作用的属性(已经够糟糕了!),我们还有
Dispatcher.FromThread(…)
,一个做完全相同事情的方法…除了现在没有副作用之外。当心!