2010-10-27 131 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>編寫一個相當容易,但它不包含在框架中。它也有些不同,因爲它不會自動將事件封送到該線程中 - 它更像是一個構建塊,可提供此類操作所需的功能。

相關問題