2017-02-08 15 views
-1

私はWindowsエクスプローラの名前空間拡張を作成しています。拡張のコンテキストでは、UIスレッドはありません。ですから、UIオブジェクトを作成して再利用するためにキャッシュすると、クロススレッド例外が発生します。なぜ私はクロススレッド例外が発生しているのか理解していますが、回避方法はわかりません。UIオブジェクトの管理とキャッシュ

独自のUIスレッドを作成し、そのスレッドを使用してUIオブジェクトを管理する方法はありますか?私はそれが問題を解決すると思う。

+0

作成した同じスレッドからUIオブジェクトを作成してアクセスしてください。メインスレッドが実行されている必要があります。そのスレッドを作成およびアクセスするために使用してください。 – JohanP

+0

私はそれを得ない、なぜdownvotes?非常に具体的な質問です。広すぎるために閉鎖するように求める人は、質問を読むべきです。 – Mayank

答えて

0

私自身のメッセージループを作成し、そこからUIを実行することでこれを解決できました。次の例では、actionはUIを呼び出すために呼び出す関数です。

internal class MessageLoop 
{ 
    private bool _running; 
    private readonly ConcurrentQueue<Action> _actions = new ConcurrentQueue<Action>(); 

    [DllImport("user32.dll")] 
    static extern int GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); 
    [DllImport("user32.dll")] 
    static extern bool TranslateMessage([In] ref MSG lpMsg); 
    [DllImport("user32.dll")] 
    static extern IntPtr DispatchMessage([In] ref MSG lpmsg); 

    public MessageLoop() 
    { 
     Start(); 
    } 

    public void Start() 
    { 
     _running = true; 
     Thread t = new Thread(RunMessageLoop) {Name = "UI Thread", IsBackground = true}; 
     t.SetApartmentState(ApartmentState.STA); 
     t.Start(); 
    } 

    private void RunMessageLoop() 
    { 
     while (_running) 
     { 
      while (_actions.Count > 0) 
      { 
       Action action; 

       if (_actions.TryDequeue(out action)) 
        action(); 
      } 

      MSG msg; 
      var res = GetMessage(out msg, IntPtr.Zero, 0, 0); 

      if (res <= 0) 
      { 
       _running = false; 
       break; 
      } 

      TranslateMessage(ref msg); 
      DispatchMessage(ref msg); 
     } 
    } 

    public void Stop() 
    { 
     _running = false; 
    } 

    public void AddMessage(Action act) 
    { 
     _actions.Enqueue(act); 
    } 
} 
関連する問題