因此... 看來信息/代碼@http://geekswithblogs.net/robp/archive/2008/03/28/why-doesnt-dispatcher-implement-isynchronizeinvoke.aspx確實提供了一個工作解決方案。 代碼完全獨立於任何UI,而僅依賴於ISynchronizeInvoke進行正確的UI /線程集成。
剛剛使用過這個,我仍然不太願意保持原樣。
我的問題的要點是,每一個事件調用函數看起來是這樣的:
protected virtual void OnLeftThumbStickMove(ThumbStickEventArgs e)
{
if (LeftThumbStickMove == null) return;
if (_syncObj == null || !_syncObj.InvokeRequired)
LeftThumbStickMove(this, e);
else
_syncObj.BeginInvoke(LeftThumbStickMove, new object[] { this, e });
}
這是非常惱人的和混亂編寫代碼這種方式,它看起來對我來說,像這樣太過計較周圍只是讓該死的東西去工作。基本上我不喜歡用這麼多的邏輯來包裝每個事件調用(!)
因此,我選擇了一個不同的/額外的策略: 基本上,XBox360GamePad類的構造函數現在看起來像這樣:
public XBox360GamePad(UserIndex controllerIndex, Func<int, Action, object> timerSetupAction)
{
CurrentController = new Controller(controllerIndex);
_timerState = timerSetupAction(10, UpdateState);
}
正如您所看到的,它接受一個負責創建計時器並掛鉤它的Func。
這意味着,在默認情況下,裏面的360個控制器類,我不需要使用任何 UI具體定時器......從本質上說,我的「默認」構造函數控制器看起來是這樣的:
public XBox360GamePad(UserIndex controllerIndex) :
this(controllerIndex, (i,f) => new Timer(delegate { f(); }, null, i, i)) {}
我使用lambda函數來編寫控制器類在定時器「service」上的依賴關係。
從WPF,我用的是更普遍的構造,以確保控制將使用DispatcherTimer這樣的:
_gamePad = new XBox360GamePad(UserIndex.One, (i, f) => {
var t = new DispatcherTimer(DispatcherPriority.Render) {Interval = new TimeSpan(0, 0, 0, 0, i) };
t.Tick += delegate { f(); };
t.Start();
return t;
});
這樣一來,我基本上把它上升到「用戶」提供計時器實現控件,其中默認實現不必使用任何WPF或WinForms特定的代碼。
我個人發現這比使用ISynchronizeInvoke更有用/更好的設計。
我很想聽到,像這樣的人反饋/要改善這種/被厭惡這等