.NET 中是否有类似于 Qt::QueuedConnection 的东西?
在 Qt 中,有一个很好的习惯用法,即让每个对象与一个线程关联,以便其所有事件处理程序将 仅在该线程中运行(当然,除非直接调用)。
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
...
In Qt, there is a nice idiom to have each object associated with a thread, so that all its event handlers will only run in that thread (unless called directly, of course).
Is there anything even remotely like that in C#/.NET? If not, how would you start writing your own?
Example:
// 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;
};
and
// 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();
}
will output:
Main thread is 3916
"Foo" in thread 3824
"Foo" in thread 3824
"Bar" in thread 3920
"Foo" in thread 3824
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
.NET 中与此最接近的类比可能是 SynchronizationContext。
例如,任务并行库使用它来将连续编组回 UI 线程。
然而,没有一个可以在任何线程上工作的内置实现。在 .NET 4 中使用
BlockingCollection
编写一个相当容易,但它不包含在框架中。它还有些不同,因为它不会自动为您将事件封送回该线程 - 它更像是一个构建块,提供此类操作所需的功能。The closest analogy to this in .NET would likely be SynchronizationContext.
This is used, for example, by the Task Parallel Library for marshalling continations back to a UI thread.
There isn't, however, a built-in implementation that works on any thread. It's fairly easy to write one using
BlockingCollection<T>
in .NET 4, but it isn't included in the Framework. It also is somewhat different, in that it doesn't automatically marshal the events back onto that thread for you - it's more of a building block that provides the functionality required for this type of operation.WPF 调度程序!
输出:
WPF Dispatcher!
Output: