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# コーダーではありませんが、Delegates、BackgroundWorkers など、これを解決するために多くのことを試しましたが、これまでのところうまくいきませんでした。

誰でもこれで私を助けることができますか?

4

2 に答える 2

2

Dispatcher を介して UI スレッドでメソッドを呼び出すことを検討してください。あなたの場合、説明した型のコンストラクターにパラメーターとして UI ディスパッチャーを渡し、それをフィールドに保存する必要があると思います。次に、呼び出し時に次のことができます。

if(this.Dispatcher.CheckAccess())
{
    InteractionService.UserInteration.DisplayPopup(...);
}
else
{
    this.Dispatcher.Invoke(()=>this.CallerID());
}
于 2013-02-22T10:19:42.090 に答える
0

独自の DispatcherHelper を記述して、ViewModel から Dispatcher にアクセスできます。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;
        }
    }
于 2013-02-22T11:06:03.190 に答える