我正在尝试异步调用具有单个instanceContextMode的WCF上的方法。
在等待异步方法时,是否有一种方法可以重用服务实例?我使用Task方式在WCF服务参考上生成异步操作。
我进行了一个测试项目,因为我的应用程序出现了一些问题。 我的TestService公开了2种方法:
由于某些其他原因,我的服务应处于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}";
}
}
我的主机是一个简单的控制台应用程序,允许我通过Console.WriteLine()方法查看WS调用:
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();
}
}
}
在我的客户端上,我只有一个简单的表单来显示结果调用:
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}";
}
这样做时,我可以在resultTestBox
和主机控制台中看到,只有在“ test2”结束之后才调用“ test3”和“ test4”。
如果我在本地进行相同的测试(而不是通过WCF服务),则行为就像预期的那样,在“ test2”等待时调用了“ test3”和“ test4”。
答案 0 :(得分:2)
如果InstanceContextMode值设置为Single,则结果是您的服务一次只能处理一条消息,除非您还将ConcurrencyMode值也设置为ConcurrencyMode。
(看起来他们忘了告诉什么ConcurrencyMode)
因此只需在您的服务上设置正确的ConcurrencyMode
:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
请确保您的代码是无状态且线程安全的。这种组合很容易出错。