WCF не имеет встроенной функции для этого, но вы можете легко создать класс, который выполнит повторную попытку за вас. Пример ниже показывает один такой способ. Обратите внимание, что если ваша привязка использует сеанс, вам может потребоваться пересоздать клиент (вместо простого повторного его использования), так как его канал, скорее всего, будет поврежден в случае ошибки.
public class StackOverflow_4968244
{
[ServiceContract]
public interface ITest
{
[OperationContract]
int Add(int x, int y);
}
public class Service : ITest
{
public int Add(int x, int y)
{
Console.WriteLine("Request at service: {0}", OperationContext.Current.Host.BaseAddresses[0]);
if (new Random().Next(3) == 0)
{
throw new InvalidOperationException("Random error");
}
return x + y;
}
}
public class Client : ClientBase<ITest>, ITest
{
public Client(string address) : base(new BasicHttpBinding(), new EndpointAddress(address)) { }
public int Add(int x, int y)
{
return this.Channel.Add(x, y);
}
}
public class SafeClient : ITest
{
List<Client> clients;
public SafeClient(params Client[] clients)
{
this.clients = new List<Client>(clients);
}
public int Add(int x, int y)
{
foreach (var client in this.clients)
{
try
{
return client.Add(x, y);
}
catch (CommunicationException)
{
Console.WriteLine("Error calling client {0}, retrying with next one", client.Endpoint.Address.Uri);
}
}
throw new InvalidOperationException("All services seem to be down");
}
}
public static void Test()
{
string baseAddress1 = "http://" + Environment.MachineName + ":8000/Service";
string baseAddress2 = "http://" + Environment.MachineName + ":8001/Service";
string baseAddress3 = "http://" + Environment.MachineName + ":8002/Service";
ServiceHost host1 = new ServiceHost(typeof(Service), new Uri(baseAddress1));
ServiceHost host2 = new ServiceHost(typeof(Service), new Uri(baseAddress2));
ServiceHost host3 = new ServiceHost(typeof(Service), new Uri(baseAddress3));
host1.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
host2.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
host3.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
host1.Open();
host2.Open();
host3.Open();
Console.WriteLine("Hosts opened");
SafeClient safeClient = new SafeClient(
new Client(baseAddress1),
new Client(baseAddress2),
new Client(baseAddress3));
for (int i = 0; i < 20; i++)
{
Console.WriteLine(safeClient.Add(i, 10));
}
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host1.Close();
host2.Close();
host3.Close();
}
}