在Qt中,每个对象associated with a thread都有一个很好的习惯用法,所以它的所有事件处理程序都会only run in that thread(当然,除非直接调用)。
在C#/ .NET中有没有类似的东西?如果没有,你会如何开始自己编写?
示例:
// threaded.h
#include <QThread>
#include <QDebug>
#include <QtGlobal>
class ThreadedObject : public QObject {
Q_OBJECT
public:
ThreadedObject(const QString &name){
Name = name;
// the default QThread implementation is an empty event loop
Thread = new QThread(this);
moveToThread(Thread);
Thread->start();
}
public slots:
void tick() {
qDebug() << Name << "in thread" << (int)QThread::currentThreadId();
}
private:
QThread *Thread;
QString Name;
};
和
// main.cpp
#include <QtCore/QCoreApplication>
#include <QTimer>
#include "threaded.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ThreadedObject *foo = new ThreadedObject("Foo");
QTimer footimer;
QObject::connect(&footimer, SIGNAL(timeout()), foo, SLOT(tick()));
ThreadedObject *bar = new ThreadedObject("Bar");
QTimer bartimer;
QObject::connect(&bartimer, SIGNAL(timeout()), bar, SLOT(tick()));
qDebug() << "Main thread is" << (int)QThread::currentThreadId();
footimer.start(1300);
bartimer.start(3240);
return a.exec();
}
将输出:
Main thread is 3916
"Foo" in thread 3824
"Foo" in thread 3824
"Bar" in thread 3920
"Foo" in thread 3824
...
答案 0 :(得分:3)
在.NET中与此最接近的类比可能是SynchronizationContext。
例如,这由Task Parallel Library用于将连续编组返回到UI线程。
但是,没有一个可在任何线程上运行的内置实现。在.NET 4中使用BlockingCollection<T>
编写一个相当容易,但它不包含在Framework中。它也有些不同,因为它不会自动将事件编组回到该线程上 - 它更像是一个构建块,它提供了此类操作所需的功能。
答案 1 :(得分:0)
WPF Dispatcher!
using System;
using System.Windows.Threading;
using System.Threading;
namespace dispatchertest
{
public class Dispatched : DispatcherObject
{
readonly object Lock = new object();
readonly string _name;
public string Name { get { return _name; } }
public Dispatched(string name) {
this._name = name;
}
public void tick(object sender, EventArgs e) {
lock ( Lock ) {
Console.WriteLine("{0} in thread {1}", Name, Thread.CurrentThread.ManagedThreadId);
}
}
}
class Program
{
static void Main(string[] args) {
var timer = new DispatcherTimer(DispatcherPriority.Send, Dispatcher.CurrentDispatcher);
Thread thread1 = new Thread(() => {
var d2 = Dispatcher.CurrentDispatcher;
var foo = new Dispatched("Foo");
var timer1 = new DispatcherTimer(DispatcherPriority.Send, Dispatcher.CurrentDispatcher);
timer1.Interval = new TimeSpan(0,0,0,0, milliseconds: 809);
timer1.Tick += foo.tick;
timer1.Start();
Dispatcher.Run();
});
var bar = new Dispatched("Bar");
timer.Tick += bar.tick;
thread1.Start();
timer.Interval = new TimeSpan(0,0,0,0, milliseconds: 1234);
timer.Start();
Dispatcher.Run();
}
}
}
输出:
Foo in thread 10
Bar in thread 9
Foo in thread 10
Foo in thread 10
Bar in thread 9
Foo in thread 10
Bar in thread 9
Foo in thread 10
Foo in thread 10
Bar in thread 9
Foo in thread 10
Bar in thread 9
Foo in thread 10
Foo in thread 10