I have a simple web-service with a one-way operation which I expected would not block the client when invoked.
With the BasicHttpBinding this is fine.
With the default WsHttpBinding the IsOneWay attribute is not taken into account (same time as a not one-way operation I've created to test).
I've found two interesting facts:
when I set SecurityMode to None it works as expected
when I set SessionMode to NotAllowed it works too
I've read that if sessions are activated messages are treated in order so that would explain the behavior.
But why setting SecurityMode to None does the trick too?
What are the relationships between these three properties and how to explain these behaviors?
Here is my "benchmark":
[ServiceContract(/*SessionMode = SessionMode.NotAllowed*/)]
interface ILogService
{
[OperationContract]
void Log(string message);
[OperationContract(IsOneWay = true)]
void LogOneWay(string message);
}
class LogService : ILogService
{
public void Log(string message)
{
Thread.Sleep(100);
}
public void LogOneWay(string message)
{
Thread.Sleep(100);
}
}
public void Run()
{
ServiceHost host = new ServiceHost(typeof(LogService));
host.AddServiceEndpoint(typeof(ILogService), new WSHttpBinding(/*SecurityMode.None*/), "http://localhost:12345/log");
host.Open();
ILogService proxy = ChannelFactory<ILogService>.CreateChannel(new WSHttpBinding(/*SecurityMode.None*/), new EndpointAddress("http://localhost:12345/log"));
proxy.Log("");
const int n = 100;
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < n; ++i)
{
proxy.LogOneWay("");
Console.WriteLine(i);
}
stopwatch.Stop();
TimeSpan datagramTime = stopwatch.Elapsed;
stopwatch.Restart();
for (int i = 0; i < n; ++i)
{
proxy.Log("");
Console.WriteLine(i);
}
stopwatch.Stop();
TimeSpan halfDuplexTime = stopwatch.Elapsed;
host.Close();
Console.WriteLine("Half-duplex: {0}", halfDuplexTime);
Console.WriteLine("Datagram: {0}", datagramTime);
}