Дуплекс WCF + Статическая коллекция COM-объектов - PullRequest
0 голосов
/ 12 ноября 2009

Я пытаюсь создать службу WCF, которая предоставляет функциональные возможности определенного COM-объекта, для которого у меня нет исходного источника. Я использую дуплексное связывание, чтобы у каждого клиента был свой экземпляр, поскольку есть события, связанные с каждым конкретным экземпляром, которые доставляются с помощью обратного вызова (IAgent). Похоже, что существует тупик или что-то в этом роде, потому что после первого действия мой сервис блокируется при блокировке моего второго действия. Я попытался реализовать эти пользовательские атрибуты STA и поведение операций (http://devlicio.us/blogs/scott_seely/archive/2009/07/17/calling-an-sta-com-object-from-a-wcf-operation.aspx), но мой OperationContext.Current всегда нулевой. Любой совет очень ценится.

Услуги

Коллекция:

private static Dictionary<IAgent, COMAgent> agents = new Dictionary<IAgent, COMAgent>();

Первое действие:

    public void Login(LoginRequest request)
    {
        IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
        lock (agents)
        {
            if (agents.ContainsKey(agent))
                throw new FaultException("You are already logged in.");
            else
            {
                ICOMClass startup = new ICOMClass();

                string server = ConfigurationManager.AppSettings["Server"];
                int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
                bool success = startup.Logon(server, port, request.Username, request.Password);

                if (!success)
                    throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log in." });

                COMAgent comAgent = new COMAgent { Connection = startup };
                comAgent.SomeEvent += new EventHandler<COMEventArgs>(comAgent_COMEvent);
                agents.Add(agent, comAgent);
            }
        }
    }

Второе действие:

    public void Logoff()
    {
        IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
        lock (agents)
        {
            COMAgent comAgent = agents[agent];
            try
            {
                bool success = comAgent.Connection.Logoff();

                if (!success)
                    throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log off." });

                agents.Remove(agent);
            }
            catch (Exception exc)
            {
                throw new FaultException(exc.Message);
            }
        }
    }

1 Ответ

0 голосов
/ 12 октября 2010

Взгляните на этот очень похожий пост: http://www.netfxharmonics.com/2009/07/Accessing-WPF-Generated-Images-Via-WCF

Вы должны использовать OperationContextScope, чтобы иметь доступ к текущему OperationContext из вновь созданного потока:

System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate
    {
        using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(context))
        {
            result = InnerOperationInvoker.Invoke(instance, inputs, out staOutputs);
        }
     }));
...