【问题标题】:Is there something analogous to Qt::QueuedConnection in .NET?.NET 中是否有类似于 Qt::QueuedConnection 的东西?
【发布时间】:2011-05-01 12:54:55
【问题描述】:

在 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 
...

【问题讨论】:

    标签: c# .net multithreading qt thread-safety


    【解决方案1】:

    WPF 调度程序!

    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
    

    【讨论】:

    • 仅供参考 - WPF 的调度程序一种特定于 WPF 的 SynchronizationContext 形式...
    【解决方案2】:

    .NET 中与此最接近的类比可能是SynchronizationContext

    例如,Task Parallel Library 使用它来将 continations 编组回 UI 线程。

    但是,没有适用于任何线程的内置实现。在 .NET 4 中使用BlockingCollection&lt;T&gt; 编写一个相当容易,但它不包含在框架中。它也有些不同,因为它不会自动为您将事件编组回该线程 - 它更像是提供此类操作所需功能的构建块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 2011-01-21
      • 1970-01-01
      • 2011-12-04
      • 2011-01-07
      • 1970-01-01
      • 2018-04-13
      相关资源
      最近更新 更多