我有一些实验代码,基本上只是试图做一个简单的场景工作。我有一个客户端正在将数据传输到多个服务。我遇到的问题是,如果其中一个服务没有正常关闭,我会得到一个我无法处理的EndpointNotFoundException。以下是我处理这个失败的尝试。实际上,我想从通道列表中删除失败的服务通道,并继续将流数据传输到仍处于运行状态的服务。定时器的东西只是在数据流开始之前给服务一个启动的机会。WCF F# - 处理服务在客户端上优雅地关闭
let prices = returns a seq of data that is streamed.
type ReplayDataStream(prices) =
let evt = new Event<_>()
member x.Replay() =
async { for line, delay in prices do
do! Async.Sleep(delay)
evt.Trigger(line) }
|> Async.StartImmediate
member x.PriceChanged = evt.Publish
let main() =
let addresses = new ResizeArray<EndpointAddress>()
let announcementService = new AnnouncementService()
let createChannels addresses =
let channels = new ResizeArray<IInputDataService>()
for (address:EndpointAddress) in addresses do
let channelFactory = new ChannelFactory<IInputDataService>(new BasicHttpBinding(), address)
let channel = channelFactory.CreateChannel()
(channel :?> ICommunicationObject).Faulted.Add(fun x ->
(channel :?> ICommunicationObject).Abort()
channels.Remove(channel) |> ignore
)
channels.Add(channel)
channels
let sendMessage(args:ElapsedEventArgs) =
let channels = createChannels addresses
for financialDataStream in prices do
let replayDataStreamA = new ReplayDataStream(financialDataStream)
for channel in channels do
try
//This is where it blows up and the try block isn't catching the exception.
replayDataStreamA.PriceChanged.Add(channel.InputStringData)
with
| :? EndpointNotFoundException as ex -> Console.WriteLine(ex.ToString())
| :? CommunicationException as ex -> Console.WriteLine(ex.ToString())
| :? Exception as ex -> Console.WriteLine(ex.ToString())
replayDataStreamA.Replay()
let timer = new System.Timers.Timer()
timer.Enabled <- true
timer.AutoReset <- false
timer.Interval <- 30000.0
timer.Start()
timer.Elapsed.Add(sendMessage)
announcementService.OnlineAnnouncementReceived.Add(fun e ->
Console.WriteLine(e.EndpointDiscoveryMetadata.Address)
addresses.Add(e.EndpointDiscoveryMetadata.Address)
)
announcementService.OfflineAnnouncementReceived.Add(fun e ->
Console.WriteLine(e.EndpointDiscoveryMetadata.Address)
addresses.Remove(e.EndpointDiscoveryMetadata.Address) |> ignore
)
let announcementServiceHost = new ServiceHost(announcementService)
try
announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());
announcementServiceHost.Open();
with
| :? System.ServiceModel.CommunicationException as ex -> Console.WriteLine(ex.ToString())
| :? System.TimeoutException as ex -> Console.WriteLine(ex.ToString())
printfn "%s" "Hit any key to close."
Console.ReadKey() |> ignore
http://stackoverflow.com/questions/2458631/wcf-c-unable-to-catch-endpointnotfoundexception/2672872#2672872 – GregC 2011-05-27 03:50:55
这是我在上面的代码中试图实现的解决方案。我怀疑我可能没有正确地将它翻译成F#。 – Beaker 2011-05-27 04:03:50