2009-08-11 100 views
6

我有一個線程調用一個從Internet獲取一些東西的對象。當這個對象充滿了所有需要的信息時,它會引發一個事件,一個對象將所有的信息。該事件由啓動該線程的控制器消耗。WPF線程和GUI如何從不同線程訪問對象?

從事件返回的對象被添加到通過視圖模型方法綁定到GUI的集合中。

問題是我不能使用帶有綁定的CheckAccess ...我該如何解決使用從其他主線程創建的對象的問題?

,我收到的時候我的對象添加到主線程的集合的錯誤是:

這種類型的CollectionView不支持從一個線程從調度線程不同其SourceCollection變化。

此所述控制器:

public class WebPingerController 
{ 
    private IAllQueriesViewModel queriesViewModel; 

    private PingerConfiguration configuration; 

    private Pinger ping; 

    private Thread threadPing; 

    public WebPingerController(PingerConfiguration configuration, IAllQueriesViewModel queriesViewModel) 
    { 
     this.queriesViewModel = queriesViewModel; 
     this.configuration = configuration; 
     this.ping = new Pinger(configuration.UrlToPing); 
     this.ping.EventPingDone += new delPingerDone(ping_EventPingDone); 
     this.threadPing = new Thread(new ThreadStart(this.ThreadedStart)); 
    } 


    void ping_EventPingDone(object sender, QueryStatisticInformation info) 
    { 
     queriesViewModel.AddQuery(info);//ERROR HAPPEN HERE 
    } 

    public void Start() 
    { 
     this.threadPing.Start(); 
    } 

    public void Stop() 
    { 
     try 
     { 
      this.threadPing.Abort(); 
     } 
     catch (Exception e) 
     { 

     } 
    } 

    private void ThreadedStart() 
    { 
     while (this.threadPing.IsAlive) 
     { 
      this.ping.Ping(); 
      Thread.Sleep(this.configuration.TimeBetweenPing); 
     } 
    } 
} 

回答

6

我找到了解決方案blog

而不是僅僅調用集合來添加線程中的對象。

queriesViewModel.AddQuery(info); 

我必須將主線程傳遞給控制器​​並使用調度程序。守衛答案非常接近。

public delegate void MethodInvoker(); 
    void ping_EventPingDone(object sender, QueryStatisticInformation info) 
    { 
     if (UIThread != null) 
     { 

      Dispatcher.FromThread(UIThread).Invoke((MethodInvoker)delegate 
      { 
       queriesViewModel.AddQuery(info); 
      } 
      , null); 
     } 
     else 
     { 
      queriesViewModel.AddQuery(info); 
     } 
    } 
+1

你可以在這裏發佈UIThread的定義嗎?謝謝。不知道在我的代碼中用什麼替代它 – Para 2012-05-20 09:30:21

+1

同樣的問題。 UIThread究竟意味着什麼? – zero51 2012-06-04 09:27:34

+0

它應該是'System.Windows.Threading.DispatcherObject'的一個子類。 – Jalal 2012-09-01 10:45:24

3

可能的解決方案是初始化主線程上的對象?

MyObject obj; 

this.Dispatcher.Invoke((Action)delegate { obj = new MyObject() }); 

編輯:在第二讀通過,這可能不是給你的模型的解決方案。你是否收到運行時錯誤?如果傳回的對象是您自己的,確保該對象是線程安全的,則可能導致CheckAccess不必要。

+0

此類CollectionView不支持從與分派器線程不同的線程更改其SourceCollection。 – 2009-08-11 16:18:51