2016-02-23 49 views
2

我一直在調查SynchronizationContext,這些文章(Understanding SynchronizationContext,ExecutionContext vs SynchronizationContext)真的幫助我,但是 - 當然 - 還有很多問題。如何正確覆蓋自定義SynchronizationContext中的Post方法?

我想實現我自己的SynchronizationContext類,該類繼承自基類,以便我可以在任何Task(用於自定義消息循環,調速,跟蹤等)的上下文中使用它。是這樣的:

public class SyncContext : System.Threading.SynchronizationContext 
{ 

    public SyncContext() : base() 
    { 
    } 

    public override void Send(Threading.SendOrPostCallback d, object state) 
    { 
     base.Send(d, state); 
    } 

    public override void Post(Threading.SendOrPostCallback d, object state) 
    { 
     base.Post(d, state); 
    } 
} 

雖然base.Send似乎做什麼期望(同步執行回調),base.Post似乎沒有做任何事情。關於Post方法微軟指出:

在派生類中重寫,調度一個異步消息 到同步上下文。

我猜的基類不能被指責爲沒有異步機制來實現,而應該當base.Post被調用或發生的事情怎麼可能是正確的/更好的實現看看嗎?我的一般做法是否已經產生誤導?

感謝您的努力!

後續問題:執行自定義TaskScheduler也許是更好的方法 - 也許TaskScheduler that uses a dedicated thread本質上是我所需要的?

+0

這是一個SynchronizationContext的關鍵,沒有別的問題。如果你不知道如何寫它,那麼你不能實現一個。它必須讓'd'代碼在另一個**特定的**線程上運行。這樣的線程必須解決[生產者 - 消費者問題](https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem)。像Winforms或WPF或UWP使用的調度器循環是標準解決方案。 –

+0

@Hans:我想我已經成功地實現了一個帶有阻塞隊列的消息循環,但是現在我正在尋找一個可以放入的包裝器。我只是想知道在SynchronizationContext中實現了Post方法的用法基類,即爲什麼它不是抽象的? – mike

+0

它不是抽象的,因爲SychronizationContext知道如何實現它。通過不同步任何東西,委託在一個線程池線程上運行。沒有用,你必須重寫它,你的Post()方法只需要將委託添加到該隊列中。 Send()方法必須執行相同的操作*和*等待隊列條目被佔用。例如,這需要將AutoResetEvent包含在隊列條目中。請記住,您正在重新創建現有的。NET SychronizationContext實現,就像[此代碼](http://stackoverflow.com/a/21684059/17034)所使用的類型。 –

回答

0

如果您有自己的消息循環,則需要在SynchronizationContext中捕獲它,因此當另一個線程調用SynchronizationContext.Post時,必須將回調操作添加到該消息循環中。

SynchronizationContext作爲ExecutionContext的一部分「流動」,但並非總是如此,因此您需要在代碼中處理流(如果可能)。

Post方法的默認實現排隊一個工作線程的動作(得到了與ILSpy):

public virtual void Post(SendOrPostCallback d, object state) 
{ 
    ThreadPool.QueueUserWorkItem(new WaitCallback(d.Invoke), state); 
} 

但最大的問題是爲什麼你需要有自己的SynchronizationContext?如果只是爲了好玩 - 那很好,否則你做的很先進,也許其他現有的更簡單的機制可以解決這個問題。

相關問題