c#-是否可以在非WPF线程上使用Dispatcher?多线程新手
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c#-是否可以在非WPF线程上使用Dispatcher?多线程新手,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4419字,纯文字阅读大概需要7分钟。
内容图文
为什么这不起作用?
我正在尝试做的是:
我需要一种在特定线程中运行特定方法的方法,该特定线程一直存在到程序结束.
我其他可能的选择:
据我了解,一种可行的方法是实现队列.我可以将要在特定线程中运行的方法推入到其中.在特定线程中,我将旋转并进入sleeping / 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.
}
}
解决方法:
您不调用Dispatcher.Run.您假设Dispatcher包含一个完成其工作的线程,但这是向后的.第一次调用Dispatcher.CurrentDispatcher时,将创建绑定到当前线程的Dispatcher.请注意,即使您的代码没有直接调用CurrentDispatcher,它也会通过构造DispatcherObject(将CurrentDispatcher捕获到一个字段中)来间接地调用它.
查看WPF threading model docs,其中包含您需要的所有详细信息.
如果要在子线程中使用类似于调度程序的功能,但又不想依赖WPF,则可以使用Nito.Async中的ActionThread类,该类大致等效于Dispatcher和专用线程.
内容总结
以上是互联网集市为您收集整理的c#-是否可以在非WPF线程上使用Dispatcher?多线程新手全部内容,希望文章能够帮你解决c#-是否可以在非WPF线程上使用Dispatcher?多线程新手所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。