c# - 使用 Single InstanceContextMode 在 WCF 服务上调用异步方法
问题描述
我正在尝试在具有单个 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
的控制台和主机控制台中看到“test3”和“test4”仅在“test2”结束后被调用。
如果我在本地(不是通过 WCF 服务)进行相同的测试,行为就像预期的那样,“test3”和“test4”在“test2”等待时被调用。
解决方案
如果 InstanceContextMode 值设置为 Single,则结果是您的服务一次只能处理一条消息,除非您还将 ConcurrencyMode 值设置为 ConcurrencyMode。
(看起来他们忘了告诉 ConcurrencyMode 是什么)
因此,只需ConcurrencyMode
在您的服务上设置权限:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
不过,请确保您的代码是无状态且线程安全的。这种组合很容易出错。
推荐阅读
- charles-proxy - 尝试拦截 iOS 请求时 charles 代理出错,但 charles 代理证书已配置且受信任
- node.js - 无法使用 node.js 在快速会话中设置 cookie
- longtable - 如何将文本包装在 longtable 的单元格中?
- drools - 如何在drools工作台中使用数据对象作为变量?
- python - Jupyter实验室 | stdin 用户输入通过。壳。进入输出单元字段
- reactjs - 如何立即将 axios.get 中的数据保存到 hooks
- javafx - getStyleableProperty 的返回类型
- react-native - React Native Camera 能够捕捉图像但不能录制视频
- django - 模型中的实用程序:可接受与否?
- c# - 如何通过 Azure Batch SDK 将文件上传到 Azure Batch 自动存储?