鉴于此界面
//read xml file
if(...your logic here...)
btn.Visibitity= System.Windows.Visibility.Visible;
我想手动(即,不使用VS中的scvutil或Add Service Reference)创建客户端代理。
我是按照以下方式做的
[ServiceContract]
public interface IProductService
{
[OperationContract]
Product Get(int id);
}
我的问题我还想要这种方法的async / await版本,只在客户端,服务器端仍然是同步的。
我希望这是一个通用解决方案,因为我有很多这种方法和服务。
答案 0 :(得分:9)
如果您正在使用ChannelFactory
来允许async-await,那么您的界面需要返回Task
或Task<T>
。
它会强制您的服务器端同时返回一个任务,但是如果您坚持要保持同步,那么您可以与Task.CompletedTask
和Task.FromResult
同步执行此操作(但如果您有选项,为什么会这样做)
例如:
[ServiceContract]
interface IProductService
{
[OperationContract]
Task<Product> GetAsync(int id);
}
class ProductService : IProductService
{
ChannelFactory<IProductService> factory;
public ProductService()
{
factory = new ChannelFactory<IProductService>("*");
}
public Task<Product> GetAsync(int id)
{
var channel = factory.CreateChannel();
return channel.GetAsync(id);
}
}
class ProductAPI : IProductService
{
public Task<Product> GetAsync(int id) => Task.FromResult(Get(id))
}
答案 1 :(得分:2)
实际上,您可以在不更改服务本身的情况下执行此操作。您只需定义第二个接口,其中包含方法的异步和[ServiceContract(Name = "NameOfTheIterfaceWhichIsActuallyExposedOnTheServer")]
返回版本,并标有GetAsync()
在您提到的示例中,您将使用[ServiceContract(Name = "IProductService")]
public interface IProductServiceAsync
{
[OperationContract]
Task<Product> GetAsync(int id);
}
操作定义第二个接口:
IProductService
即使您的服务仍在实施并公开ChannelFactory<IProductServiceAsync>
,您也可以使用GetFoo
来调用它。只要方法名称与GetFooAsync
/ Optional
模式匹配,所有内容都将正常工作。这就是Visual Studio中添加服务引用的方式可以为您生成同步服务的异步服务引用。
有关此工作的详细说明,请参阅Calling a synchronous WCF method asynchronously using ChannelFactory。