簡體   English   中英

在特定線程中運行代碼

[英]Run code in a specific thread

我有一個與外部庫對話的控制台應用程序。 不幸的是,對庫的所有調用必須從同一線程進行。

如何將方法調用從一個線程發送到另一個線程? (並且,顯然,將方法結果發送回調用線程。)

(不,這與GUI編程無關。不,使用GUI消息泵將不起作用。)

我真正想要的是使特定類上的每個方法始終在同一線程中執行。 但是我不知道該怎么做。

我的建議是執行Windows Forms和WPF的操作以設置其單線程消息泵-繼承SynchronizationContext http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext%28v=vs.110%29.aspx

在您的實現中,您將需要維護一個類似於以下內容的線程安全消息隊列: http : //www.codeproject.com/Articles/56369/Thread-safe-priority-queue-in-C您的消息泵工作線程將不斷檢查新的委托,並調用它們。

那么,為什么不只寫一個消息泵呢?

好吧,通過繼承SynchronizationContext ,您可以免費獲得所有CLR好東西,例如BackgroundWorkerAsyncOperationManager和新的await/async模式關鍵字! 他們都將神奇地加入您的庫線程中。

這是基本消息泵的一些代碼。 沒有實現SynchronizationContext

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace MessagePump
{
    class Program
    {
        static void Main(string[] args)
        {
            MessagePump p = new MessagePump();
            p.Start();
            p.AddMessage(() => Console.WriteLine("message 1"));
            p.AddMessage(() => Console.WriteLine("message 2"));
            p.AddMessage(() => Console.WriteLine("message 3"));

            Console.ReadLine();
            p.Stop();
        }
    }

    class MessagePump
    {
        bool m_Working = false;
        Queue<Action> m_Actions = new Queue<Action>();

        public void Start()
        {
            m_Working = true;
            Thread t = new Thread(DoPump);
            t.Name = "Message Pump Thread";
            t.Start();
        }
        void DoPump()
        {
            while (m_Working)
            {
                try
                {
                    Monitor.Enter(m_Actions);
                    while (m_Actions.Count > 0)
                    {
                        m_Actions.Dequeue()(); //dequeue and invoke a delegate
                    }
                }
                finally
                {
                    Monitor.Exit(m_Actions);
                }

                Thread.Sleep(100); //dont want to lock this core!
            }
        }
        public void Stop()
        {
            m_Working = false;
        }

        public void AddMessage(Action act)
        {
            lock (m_Actions)
            {
                m_Actions.Enqueue(act);
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM