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();
        }
    }
}

I'm trying to add something to a opensource software package made in C# but I'm having problems with it. The problem with the above (simplified) example is that once InteractionService.UserIntraction.DisplayPopup is called I get an exception "The calling thread cannot access this object because a different thread owns it".

I am not a C# coder but I have tried many things to solve this like Delegates, BackgroundWorkers, etc. etc. and none have worked for me so far.

Can anybody help me with this?

2
  • What is something. Where is your Interaction.DisplayPopup code? A delegate should be able to solve the issue Commented Feb 22, 2013 at 10:20
  • Related: stackoverflow.com/questions/11923865/… Commented Feb 22, 2013 at 14:29

2 Answers 2

2

Consider calling the method on the UI thread through the Dispatcher. In your case I believe you should pass in the UI dispatcher as a parameter to the constructor of the type you've described and save it in a field. Then, when calling you can do the following:

if(this.Dispatcher.CheckAccess())
{
    InteractionService.UserInteration.DisplayPopup(...);
}
else
{
    this.Dispatcher.Invoke(()=>this.CallerID());
}
Sign up to request clarification or add additional context in comments.

2 Comments

I have already tried that but the problem is that the Dispatcher isn't available in the ModuleBase class and I wasn't successful at adding one. :(
There is the ConsoleHoster open-source WPF project, where the Dispatcher is being passed in to the VM. You can take a look to the ViewModelBase class in there to see how its done. But the solution is the same. The link to it is: consolehoster.codeplex.com
0

You can write your own DispatcherHelper to acces the Dispatcher from ViewModels. I think it is MVVM friendly. We used an implementation in our app like this:

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;
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.