We are consuming wcf services on the silverlight application trough creating proxies using ChanellFacotry.
我们正在使用silverlight应用程序上的wcf服务,通过ChanellFacotry创建代理。
The Operation and Data contracts are exposed to silverlight trough assembly, which is consist of shared files from serverside Data and Operation contract libriary. (omg I hope you understand what I am saying).
操作和数据合同暴露在silverlight槽组件中,这是由服务器端数据和操作合同libriary共享的文件组成的。(天啊,我希望你能理解我的意思)。
So server and client are using same operation and data contracts.
因此服务器和客户端使用相同的操作和数据契约。
Silverlight wcf client lib has a restriction to not be able to call wcf methods synchronously, as you know, so shared operation contract file has to expose asyn versions of each operation.
Silverlight wcf客户端库有一个限制,即不能同步调用wcf方法,如您所知,因此共享操作契约文件必须公开每个操作的asyn版本。
Writing async WCF service would make some sense if they were not containing blocking operations, but as we are using EF, asyncrhony is achieved by delegating blocking work to thread pool. This is what WCF do for synch methods anyway. And this fact makes me want to tear my eyes out (#@%!^%!@%).
如果异步WCF服务不包含阻塞操作,那么编写它是有意义的,但是当我们使用EF时,异步是通过将阻塞工作委托给线程池来实现的。这就是WCF对同步方法的作用。,这个事实使我想要撕裂我的眼睛(# @ % ! ^ % @ %)。
Our project consultant has power to not allow generate dynamic proxies on the client to call synch operation contract methods (google Yevhen Bobrov Servelat Pieces if you are interested). So we have to write senseles implementations of async methods on serverside, without any performance gain (blocking calls as you remember).
我们的项目顾问有权不允许在客户端上生成动态代理来调用同步操作契约方法(如果您感兴趣,可以使用谷歌Yevhen Bobrov Servelat片段)。因此,我们必须在服务器端编写异步方法的senseles实现,而不增加任何性能(如您所记得的那样,阻塞调用)。
Is it possible to call wcf web service synchronous method from silverlight using its data contract?
是否可以使用silverlight的数据契约调用wcf web服务同步方法?
Have you ever faced this problem before, if so how did you solve it?
你以前遇到过这个问题吗?如果有,你是怎么解决的?
At the momment I am looking forward for generating async contracts for client side only using serverside contracts as a transformation source. Maybe there are some t4 template that can nicely do it for me?
在这个时刻,我希望仅使用服务器端契约作为转换源为客户端生成异步契约。也许有一些t4模板可以很好地为我做?
Sorry for the wall of text, just to mix some code to my question, this is how async contract implementation looks at the momment:
抱歉,这里有一大堆文本,我的问题是,这是异步契约实现的模式:
/// <summary>
/// Subscribes to users of the specified organization.
/// </summary>
/// <param name="organizationId">The organization id.</param>
public void Unsubscribe(int organizationId)
{
var clientId = this.OperationContext.GetClientId();
if (string.IsNullOrEmpty(clientId))
{
return;
}
this.InternalUnsubscribe(organizationId, clientId);
}
/// <summary>
/// Begins an asynchronous operation to Unsubscribe.
/// </summary>
/// <param name="organizationId">The organization id.</param>
/// <param name="callback">The callback.</param>
/// <param name="passThroughData">The pass through data.</param>
/// <returns>
/// An implementation of <see cref="IAsyncResult"/> that provides access to the state or result of the operation.
/// </returns>
public IAsyncResult BeginUnsubscribe(int organizationId, AsyncCallback callback, object passThroughData)
{
var clientId = this.OperationContext.GetClientId();
if (string.IsNullOrEmpty(clientId))
{
return null;
}
var asyncResult = new VoidAsyncResult(callback, passThroughData);
Task.Factory.StartNew(() =>
{
try
{
this.InternalUnsubscribe(organizationId, clientId);
asyncResult.SetAsCompleted(false);
}
catch (Exception ex)
{
asyncResult.SetAsCompleted(ex, false);
}
});
return asyncResult;
}
/// <summary>
/// Ends an existing asynchronous operation to Unsubscribe.
/// </summary>
/// <param name="result">The <see cref="IAsyncResult"/> provided by the BeginUnsubscribe operation.</param>
public void EndUnsubscribe(IAsyncResult result)
{
var response = result as VoidAsyncResult;
if (response != null)
{
response.EndInvoke();
}
}
1 个解决方案
#1
3
You do not need to write the WCF service to be Async. You simple need to make a ServiceContract for your service that defines the Async methods. Here's a quick example
不需要将WCF服务编写为异步的。您只需为定义异步方法的服务创建ServiceContract。这是一个简单的例子
[ServiceContract]
public interface IMyService
{
[OperationContract]
int Foo(string input);
}
//tell wcf that this contract applies to IMyService
[ServiceContract(Name = "IMyService")]
public interface IMyServiceAsync
{
//setting AsyncPattern = true allows WCF to map the async methods to the sync ones.
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFoo(string input, AsyncCallback callback, object asyncState);
int EndFoo(IAsyncResult result};
}
// you only need to implement the sync contract
public class MyService : IMyService
{
public int Foo(string input)
{
return input.Length;
}
}
Now use IMyServiceAsync with your ChannelFactory and everything should work.
现在使用IMyServiceAsync与你的频道工厂和一切应该工作。
#1
3
You do not need to write the WCF service to be Async. You simple need to make a ServiceContract for your service that defines the Async methods. Here's a quick example
不需要将WCF服务编写为异步的。您只需为定义异步方法的服务创建ServiceContract。这是一个简单的例子
[ServiceContract]
public interface IMyService
{
[OperationContract]
int Foo(string input);
}
//tell wcf that this contract applies to IMyService
[ServiceContract(Name = "IMyService")]
public interface IMyServiceAsync
{
//setting AsyncPattern = true allows WCF to map the async methods to the sync ones.
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFoo(string input, AsyncCallback callback, object asyncState);
int EndFoo(IAsyncResult result};
}
// you only need to implement the sync contract
public class MyService : IMyService
{
public int Foo(string input)
{
return input.Length;
}
}
Now use IMyServiceAsync with your ChannelFactory and everything should work.
现在使用IMyServiceAsync与你的频道工厂和一切应该工作。