I'm trying to call asynchronously a method on a WCF which has a single instanceContextMode.
Is there a way reuse an instance of a service while it is waiting for an asynchronous method ? I use the Task way for generating async operations on my WCF service reference.
I made a testing project because I had some problems on my application. My TestService expose 2 methods :
- - A fast method which should be called synchronously
- - A long method which should be called asynchronously
For some other reasons, my service should be in Single instanceContextMode:
[ServiceContract]
public interface ITestService
{
[OperationContract]
string FastMethod(string name);
[OperationContract]
Task<string> LongMethodAsync(string name);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class TestService : ITestService
{
public TestService() { }
public string FastMethod(string name)
{
Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - FastMethod call - {name}");
return $"FastMethod - {name}";
}
public async Task<string> LongMethodAsync(string name)
{
for (int i = 5; i > 0; i--)
{
await Task.Delay(1000);
Console.WriteLine($"LongMethod pending {i}");
}
Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - LongMethod call - {name}");
return $"LongMethod - {name}";
}
}
My host is a simple console application which allow me to see WS calls through Console.WriteLine() methods:
class Program
{
static void Main(string[] args)
{
using (ServiceHost hostTest = new ServiceHost(typeof(TestService)))
{
Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Service starting...");
hostTest.Open();
Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Service started");
Console.ReadKey();
hostTest.Close();
}
}
}
On my client side, I only have a simple form which show result calls:
private async void button1_Click(object sender, EventArgs e)
{
string result;
result = srvClient.FastMethod("test1");
resultTextBox.Text = $"{DateTime.Now.ToLongTimeString()} - {result}";
Task<string> t1 = srvClient.LongMethodAsync("test2");
result = srvClient.FastMethod("test3");
resultTextBox.Text += $"\r\n{DateTime.Now.ToLongTimeString()} - {result}";
System.Threading.Thread.Sleep(1000);
result = srvClient.FastMethod("test4");
resultTextBox.Text += $"\r\n{DateTime.Now.ToLongTimeString()} - {result}";
result = await t1;
resultTextBox.Text += $"\r\n{DateTime.Now.ToLongTimeString()} - {result}";
}
When I do that I can see in my resultTestBox and in the host Console that "test3" and "test4" are called only after the end of "test2".
If I do the same test locally (not through a WCF service) the behavoir is like expected, the "test3" and "test4" are called while "test2" is waiting.