У меня есть простая служба WCF, которая отправляет уведомления в приложение и из него.
служба хранит статический список подписчиков и, прежде чем попытаться отправить сообщение любому из них, проверяет ...
((ICommunicationObject)callback).State == CommunicationState.Opened
к сожалению, если приложение, потребляющее службу WCF, перестает работать - таким образом, не отписываясь от службы WCF, служба будет зависать и, в конечном итоге, отключаться. далеко от идеала.
в попытке отсортировать это я добавил
OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted);
в методе подписки, но он никогда не срабатывает.
Есть ли надежный способ определить, действительно ли открыт канал обратного вызова?
или, может быть, асинхронно отправлять сообщения, чтобы, если подписчик появился в списке, но на самом деле умер, служба не будет ждать, как выродок, стоящий на свидании? :)
любая помощь, полученная наиболее счастливо
спасибо
нац
полный код для обслуживания ниже ...
private static readonly List<INotificationCallback> subscribers = new List<INotificationCallback>();
public void AddMessage(string SendingUser, string message, List<string> users, MessageType messageType, Guid? CaseID)
{
subscribers.ForEach(delegate(INotificationCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
callback.OnMessageAdded(SendingUser, message, users, messageType, DateTime.Now, CaseID);
}
else
{
RemoveSubscriber(callback);
}
});
}
public bool Subscribe()
{
try
{
INotificationCallback callback = OperationContext.Current.GetCallbackChannel<INotificationCallback>();
OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted);
OperationContext.Current.Channel.Closed += new EventHandler(Channel_Closed);
if (!subscribers.Contains(callback))
subscribers.Add(callback);
return true;
}
catch
{
return false;
}
}
private void RemoveSubscriber(INotificationCallback callback)
{
if (subscribers.Contains(callback))
subscribers.Remove(callback);
}
void Channel_Closed(object sender, EventArgs e)
{
INotificationCallback machine = sender as INotificationCallback;
RemoveSubscriber(machine);
}
void Channel_Faulted(object sender, EventArgs e)
{
INotificationCallback machine = sender as INotificationCallback;
RemoveSubscriber(machine);
}
public bool Unsubscribe()
{
try
{
INotificationCallback callback = OperationContext.Current.GetCallbackChannel<INotificationCallback>();
RemoveSubscriber(callback);
return true;
}
catch
{
return false;
}
}