这只是在客户端,我已经跳过了旧的事件驱动异步 bleh 模式,并将其替换为异步等待模式。不等待 webmethod 调用异步,并阻塞 UI...甚至不属于本世纪 ;)
如果您使用的是 .net 4.5+,您将免费获得 async-await 模式(除非 wp8,您仍然需要在其中包装它)。异步方法应该已经可以通过服务使用。如果您使用的是旧框架,我推荐AsyncBridge,它允许您在这种情况下使用异步等待模式。另一种选择是坚持旧的事件驱动的异步噩梦。以下示例只有在您使用 C#5.0 或从不使用时才可能。
确保从非异步方法在新线程中启动。
Task.Factory.StartNew(client.DoSomethingAsync("blabla") ).ContinueWith(...);
最后一部分在你的方法完成后运行,检查完成代码的异常等。
或者在一些异步方法中
public async Task<string> DoSomethingAsync(String text) {
// Exception handling etc
return await client.DoSomethingAsync(text);
}
将 APM 包装为异步等待模式:
public class ServiceWrapper : IServiceWrapper
{
readonly YourServiceClient client;
public ServiceWrapper(YourServiceClient client)
{
this.client = client;
}
public async Task<string> DoSomethingAsync(string someParameter)
{
return await Task<string>.Factory.FromAsync(client.BeginDoSomeStuff, client.EndDoSomeStuff, someParameter, new object());
}
}
编辑
在包装服务中打开和关闭连接。 (我现在没有可用的 devbox,但这应该可以)。
public class ServiceWrapper : IServiceWrapper
{
EndpointAddress address;
public ServiceWrapper(EndpointAddress clientAddress)
{
address = clientAddress;
}
public async Task<string> DoSomethingAsync(string someParameter)
{
// handle exceptions etc here, can be done some cleaner..
var client = new YourServiceClient();
client.Endpoint.Address = address.Address; // can skip this..
await client.OpenAsync()
var res = await Task<string>.Factory.FromAsync(client.BeginDoSomeStuff, client.EndDoSomeStuff, someParameter, new object());
await client.CloseAsync();
return res;
}
}
最后一件事我不确定你是如何生成代理的,如果你使用 vs 确保在配置服务时勾选允许异步方法的复选框。如果您使用的是 svcutil,请添加适当的标志。
Async-await pattern
Old event driven async pattern
希望对你有帮助,
干杯,
斯蒂安