<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                DispatcherObject,Dispatcher,Thread之間的關系 我們都知道WPF中的控件類都是從System.Windows.Threading.DispatcherObject繼承而來, 而DispatcherObject又在構造時與當前線程的Dispatcher關聯起來,CurrentDispatcher如果為null則會主動new一個Dispatcher并且在構造時和當前創建它的線程關聯起來了。因此整個鏈為DispatcherObject <- Dispatcher <- Thread. 具體我們一起看看反編譯的紅色代碼: public abstract class DispatcherObject { ? private Dispatcher _dispatcher; ? [EditorBrowsable(EditorBrowsableState.Advanced)] ? public Dispatcher Dispatcher ? { ? ? get ? ? { ? ? ? return this ._dispatcher; ? ? } ? } ? protected DispatcherObject() ? { ? ? base .\u002Ector(); ? ? this ._dispatcher = Dispatcher.CurrentDispatcher; ? } ? ?........................................................ } public sealed class Dispatcher { ? ??public static Dispatcher CurrentDispatcher ? ?{ ? ? get ? ? { ? ? ? return Dispatcher.FromThread(Thread.CurrentThread) ?? new Dispatcher(); ? ? } ? ?} ? private Dispatcher() ? { ? ?............................. ? ? Dispatcher._tlsDispatcher = this ; ? ? this ._dispatcherThread = Thread.CurrentThread; ? ?............................. ? } ? ?.............................. } 這樣設計的原則就保證:界面元素只有被創建它的線程訪問 Dispatcher中Invoke,BeginInvoke和Win32中SendMessage,PostMessage的關系 上面我們提到wpf的界面元素只有被創建它的線程來訪問,如果我們想在后臺或者其他線程里該怎么辦? 答案就是利用Dispatcher的Invoke和BeginInvoke,作用就是把委托放到界面元素關聯的Dispatcher里的工作項里,然后此Dispatcher關聯的線程進行執行。 所不同的是Invoke是在關聯的線程里同步執行委托, 而BeginInvoke是在關聯的線程里異步執行委托。 做過Win32或者MFC編程的童鞋們都知道win32中有SendMessage和PostMessage類似的概念,這些概念有什么內在關系呢? 其實Dispatcher的Invoke和BeginInvoke都是調用Win32的PostMessage傳遞窗體句柄和消息號,反編譯代碼如下: ? private bool RequestForegroundProcessing() ? { ? ? if (this._postedProcessingType >= 2) ? ? ? return true; ? ? if (this._postedProcessingType == 1) ? ? ? SafeNativeMethods.KillTimer(new HandleRef((object) this, this._window.Value.Handle), 1); ? ? this._postedProcessingType = 2; ? ? return MS.Win32.UnsafeNativeMethods.TryPostMessage(new HandleRef((object) this, this._window.Value.Handle), Dispatcher._msgProcessQueue, IntPtr.Zero, IntPtr.Zero); ? } 只不過Invoke在PostMessage后調用了內部返回值DispatcherOperation的wait方法,在執行結束后才返回。反編譯代碼如下: ? ??DispatcherOperation dispatcherOperation = this.BeginInvokeImpl(priority, method, args, isSingleParameter); ? ? ? if (dispatcherOperation != null) ? ? ? { ? ? ? ? int num = (int) dispatcherOperation.Wait(timeout); ? ? ? ? if (dispatcherOperation.Status == DispatcherOperationStatus.Completed) ? ? ? ? ? obj = dispatcherOperation.Result; ? ? ? ? else if (dispatcherOperation.Status == DispatcherOperationStatus.Aborted) ? ? ? ? ? obj = (object) null; ? ? ? ? else ? ? ? ? ? dispatcherOperation.Abort(); ? ? ? } WPF的消息泵和Win32的消息泵之間的關系 WPF的窗體程序都必須隱式或者顯式調用[Application.Run()](http://msdn.microsoft.com/en-us/library/ms597010(v=vs.110).aspx)來初始化WPF窗體。當Application.Run()調用時, 會在其內部調用Dispatcher.Run()方法。最終會在PushFrame()方法內初始化消息泵。 具體為:Application.Run() -> Dispatcher.Run() -> Dispatcher.PushFrame() -> Dispatcher.PushFrameImpl() private void PushFrameImpl(DispatcherFrame frame) ? { ? ? MSG msg = new MSG(); ? ? ++this._frameDepth; ? ? try ? ? { ? ? ? SynchronizationContext current = SynchronizationContext.Current; ? ? ? bool flag = current != this._dispatcherSynchronizationContext; ? ? ? try ? ? ? { ? ? ? ? if (flag) ? ? ? ? ? SynchronizationContext.SetSynchronizationContext((SynchronizationContext) this._dispatcherSynchronizationContext); ? ? ? ? while (frame.Continue && this.GetMessage(ref msg, IntPtr.Zero, 0, 0)) ? ? ? ? ? this.TranslateAndDispatchMessage(ref msg); ? ? ? ? if (this._frameDepth != 1 || !this._hasShutdownStarted) ? ? ? ? ? return; ? ? ? ? this.ShutdownImpl(); ? ? ? } ? ? ? finally ? ? ? { ? ? ? ? if (flag) ? ? ? ? ? SynchronizationContext.SetSynchronizationContext(current); ? ? ? } ? ? } ? ? finally ? ? { ? ? ? --this._frameDepth; ? ? ? if (this._frameDepth == 0) ? ? ? ? this._exitAllFrames = false; ? ? } ? } Ok,從上述反編譯的代碼可以看到,WPF還是通過Dispatcher內部實現了傳統的Win32消息循環, 如GetMessage,TranslateMessage,DispatchMessage。 下面是win32消息泵的實現, 大家可以對比下: BOOL bRet; while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0) { ?? if (bRet == -1) ?? { ?????? // handle the error and possibly exit ?? } ?? else ?? { ?????? TranslateMessage(&msg); ?????? DispatchMessage(&msg); ?? } }
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看