在silverlight上异步调用同步WCF操作契约方法

v00*_*d00 5 .net silverlight wcf asynchronous

我们正在使用ChanellFacotry通过创建代理来使用Silverlight应用程序上的wcf服务.

操作和数据合同暴露于silverlight槽组件,该组件由来自服务器端数据和操作合同库的共享文件组成.(omg我希望你明白我在说什么).

因此服务器和客户端使用相同的操作和数据协定.

如您所知,Silverlight wcf客户端lib具有无法同步调用wcf方法的限制,因此共享操作契约文件必须公开每个操作的asyn版本.

如果它们不包含阻塞操作,编写异步WCF服务会有所帮助,但是当我们使用EF时,通过将阻塞工作委托给线程池来实现asyncrhony.无论如何,这就是WCF为同步方法所做的事情.这个事实让我想要睁开眼睛(#@%!^%!@%).

我们的项目顾问有权不允许在客户端生成动态代理来调用同步操作合同方法(谷歌Yevhen Bobrov Servelat Pieces,如果你感兴趣的话).因此,我们必须在服务器端编写异步方法的senseles实现,而不会产生任何性能提升(在您记忆时阻止调用).

是否可以使用其数据协定从silverlight调用wcf web服务同步方法?

您以前遇到过这个问题,如果是这样,您是如何解决的?

在此,我期待仅使用服务器端合同作为转换源为客户端生成异步合同.也许有一些t4模板可以很好地为我做到这一点?

对于文本墙感到抱歉,只是为了将一些代码混合到我的问题中,这就是异步合同实现如何看待这个问题:

    /// <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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

cad*_*ll0 3

您不需要将 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在将 IMyServiceAsync 与 ChannelFactory 结合使用,一切都应该可以正常工作。