异步调用WCF同步经营合同法上的Silverlight [英] Call synchronous WCF operation contract methods asynchronously on silverlight

查看:112
本文介绍了异步调用WCF同步经营合同法上的Silverlight的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在对Silverlight应用程序创建槽使用ChanellFacotry代理消费WCF服务。

的操作和数据的合同被暴露在Silverlight的槽组件,它是由来自服务器端的数据和操作合同libriary共享文件。 (OMG我希望你明白我的意思)。

所以,服务器和客户端使用相同的操作和数据的合同。

Silverlight的WCF客户端的lib有限制不能WCF方法调用同步,如你所知,这样的共享操作的合同文件中有揭露ASYN每个操作的版本。

写作异步WCF服务将使某种意义上说,如果他们不含有阻塞操作,但我们使用的是EF,asyncrhony由委托阻止工作线程池来实现。这是WCF做同步的方法呢。这一事实让我想撕毁我的眼睛(#@%^!%!@%)。

我们的项目顾问有权不允许生成客户端上的动态代理调用同步操作合同法(谷歌耶夫亨博布罗夫Servelat件,如果你有兴趣)。因此,我们有(你还记得阻塞调用)写在服务器端异步方法senseles实现,而没有任何的性能提升。

是否有可能从Silverlight中使用它的数据合同调用WCF Web服务同步的方法?

你以前遇到这个问题,如果是的话你怎么解决呢?

在momment我期待着产生异步合约客户端只使用服务器端的合同作为一个转型的来源。也许有一些T4模板,可以很好地做到这一点对我?

抱歉文本的墙上,只是把一些code我的问题,这是合同如何异步执行着眼于momment:

  ///<总结>
    ///订阅到指定的机构用户。
    ///< /总结>
    ///< PARAM NAME =organizationId>组织ID< /参数>
    公共无效退订(INT organizationId)
    {
        VAR客户端ID = this.OperationContext.GetClientId();
        如果(string.IsNullOrEmpty(客户端ID))
        {
            返回;
        }

        this.InternalUnsubscribe(organizationId,ClientID的);
    }

    ///<总结>
    ///开始一个异步操作退订。
    ///< /总结>
    ///< PARAM NAME =organizationId>组织ID< /参数>
    ///< PARAM NAME =回调>将回调< /参数>
    ///< PARAM NAME =passThroughData>在穿过数据和LT; /参数>
    ///<返回>
    ///中℃的执行情况;看到CREF =IAsyncResult的/>提供访问操作的状态和结果。
    ///< /回报>
    公众的IAsyncResult BeginUnsubscribe(INT organizationId,AsyncCallback的回调,对象passThroughData)
    {
        VAR客户端ID = this.OperationContext.GetClientId();
        如果(string.IsNullOrEmpty(客户端ID))
        {
            返回null;
        }

        VAR asyncResult =新VoidAsyncResult(回调,passThroughData);
        Task.Factory.StartNew(()=>
            {
                尝试
                {
                    this.InternalUnsubscribe(organizationId,ClientID的);
                    asyncResult.SetAsCompleted(假);
                }
                赶上(例外前)
                {
                    asyncResult.SetAsCompleted(例如,假);
                }
            });
        返回asyncResult;
    }

    ///<总结>
    ///结束现有的异步操作退订。
    ///< /总结>
    ///< PARAM NAME =结果>的<看到CREF =IAsyncResult的/> ,由BeginUnsubscribe操作&LT提供的; /参数>
    公共无效EndUnsubscribe(IAsyncResult的结果)
    {
        VAR响应=结果为VoidAsyncResult;
        如果(响应!= NULL)
        {
            response.EndInvoke();
        }
    }
 

解决方案

您不必写WCF服务是异步。你简单的需要作出的ServiceContract为您服务定义异步方法。这里有一个简单的例子

  [的ServiceContract]
公共接口IMyService
{
    [OperationContract的]
    INT美孚(字符串输入);
}

//告诉WCF本合同适用于IMyService
[的ServiceContract(NAME =IMyService)
公共接口IMyServiceAsync
{
    //设置AsyncPattern = true,允许WCF映射异步方法同步的。
    [OperationContract的(AsyncPattern =真)
    IAsyncResult的BeginFoo(字符串输入,AsyncCallback的回调,对象asyncState);

    INT EndFoo(IAsyncResult的结果};
}

//你只需要实现同步合同
公共类为MyService:IMyService
{
    公众诠释美孚(字符串输入)
    {
        返回input.Length;
    }
}
 

现在使用IMyServiceAsync您的ChannelFactory,一切都应该工作。

We are consuming wcf services on the silverlight application trough creating proxies using 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).

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.

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 (#@%!^%!@%).

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).

Is it possible to call wcf web service synchronous method from silverlight using its data contract?

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?

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();
        }
    }

解决方案

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

[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.

这篇关于异步调用WCF同步经营合同法上的Silverlight的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆