2013-02-22 174 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; 
     } 
    }