Я пытаюсь создать службу 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 всегда равен нулю. Любые советы очень ценятся.Дуплекс WCF + Статическая коллекция объектов COM
Сервис
Коллекция:
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);
}
}
}