2013-02-22 113 views
0
using System; 
using System.Linq; 
using Microsoft.Practices.Prism.MefExtensions.Modularity; 
using Samba.Domain.Models.Customers; 
using Samba.Localization.Properties; 
using Samba.Persistance.Data; 
using Samba.Presentation.Common; 
using Samba.Presentation.Common.Services; 
using System.Threading; 


namespace Samba.Modules.TapiMonitor 
{ 
    [ModuleExport(typeof(TapiMonitor))] 
    public class TapiMonitor : ModuleBase 
    { 

     public TapiMonitor() 
     { 
      Thread thread = new Thread(() => OnCallerID()); 
      thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA 
      thread.Start(); 
     } 

     public void CallerID() 
     { 
      InteractionService.UserIntraction.DisplayPopup("CID", "CID Test 2", "", ""); 
     } 

     public void OnCallerID() 
     { 
      this.CallerID(); 
     } 
    } 
} 

我試圖添加一些東西到C#中的開源軟件包,但我遇到了問題。上述(簡化)示例的問題是,一旦調用了InteractionService.UserIntraction.DisplayPopup,我就會得到一個異常「調用線程無法訪問此對象,因爲不同的線程擁有它」。C#WPF從工作線程更新UI

我不是C#編碼器,但我已經嘗試了很多事情來解決這個問題,如委託人,BackgroundWorkers等等,迄今爲止還沒有人爲我工作。

有人可以幫我嗎?

+0

什麼是東西。 Interaction.DisplayPopup代碼在哪裏?一個代表應該能夠解決的問題 – 2013-02-22 10:20:28

+0

相關:http://stackoverflow.com/questions/11923865/how-to-deal-with-cross-thread-access-exceptions – 2013-02-22 14:29:44

回答

2

考慮通過分派器調用UI線程上的方法。 在你的情況下,我相信你應該將UI調度器作爲參數傳遞給你描述的類型的構造函數,並將其保存在一個字段中。然後,打電話,你可以做的時候以下幾點:

if(this.Dispatcher.CheckAccess()) 
{ 
    InteractionService.UserInteration.DisplayPopup(...); 
} 
else 
{ 
    this.Dispatcher.Invoke(()=>this.CallerID()); 
} 
+0

我已經嘗試過,但問題是, Dispatcher在ModuleBase類中不可用,並且我沒有成功添加一個。 :( – Demigod 2013-02-22 10:27:18

+0

有一個ConsoleHoster開源WPF項目,Dispatcher被傳遞給VM,你可以看看ViewModelBase類,看看它是如何完成的,但解決方案是一樣的。它是:http://consolehoster.codeplex.com – Artak 2013-02-22 10:49:26

0

您可以編寫自己的DispatcherHelper從存取權限的ViewModels的調度。我認爲這是MVVM友好的。我們在我們的應用中使用瞭如下實現:

public class DispatcherHelper 
    { 
     private static Dispatcher dispatcher; 

     public static void BeginInvoke(Action action) 
     { 
      if (dispatcher != null) 
      { 
       dispatcher.BeginInvoke(action); 
       return; 
      } 
      throw new InvalidOperationException("Dispatcher must be initialized first"); 
     } 

     //App.xaml.cs 
     public static void RegisterDispatcher(Dispatcher dispatcher) 
     { 
      DispatcherHelper.dispatcher = dispatcher; 
     } 
    }