2010-10-27 121 views
1

在Qt中,每个对象associated with a thread都有一个很好的习惯用法,因此它的所有事件处理函数将会是only run in that thread(除非直接调用)。有没有类似于.NET中的Qt :: QueuedConnection的东西?

在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

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 
+0

只是一个供参考 - WPF的调度** **是的的SynchronizationContext的形式是WPF特定... – 2011-12-02 18:23:14

3

最接近类似于这在.NET将可能是SynchronizationContext

例如,它被任务并行库用于编组恢复到UI线程。

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

相关问题