WCF服务契约实现中的多线程操作

4
最近我看到一个项目使用了后台工作者来执行一些操作(从其他Web服务获取数据),然后通过事件将数据传递给客户端。这个项目是一个WCF服务,由另一个类库作为WCF客户端角色使用,并依次将事件抛出到应用程序中。我对这个多线程系列很感兴趣,于是进行了调查。我发现这是一个basicHttpBinding绑定,服务的唯一行为是UseSynchronizationContext=false。我发现他们在遇到未解释的异常之后添加了这个行为,这是正常的 :)
现在我的问题是关于basicHttpBinding的默认并发模式。他们不应该将其设置为可重入吗?或者这是默认行为?
如果WCF服务从客户端关闭,这种情况是否会继续失败?
我认为,在一个依赖于IIS处理的ASP.NET项目中,使用多线程操作的WCF服务是不好的,因为页面可能在WCF服务将数据返回给客户端类库并将其附加到页面之前就已经发送到客户端了。
您能否讨论一下上述内容并阐述您的想法?
当需要这样的异步编程风格时,通知WCF消费者使用CallbackContracts和内嵌WCF技术在长时间操作后通知他们而不是使用多线程操作,这样不是更好吗?
需要澄清并纠正设计,以及提供一些证明这是一个糟糕的服务架构的证据,如果这是真的话,我怀疑它!
谢谢。
1个回答

2
这并不是本质上的糟糕架构,但听起来可能会产生许多潜在陷阱。
WCF客户端库将所有协调工作留给了ASP.NET应用程序。如果ASP.NET应用程序没有检查对WCF服务的调用是否已完成,那么它就有风险在变量被设置为服务值之前使用它们,以及其他一些竞争条件,除非明确地设置某种协调初始调用与完成事件的方式。
我的建议是将WCF客户端异步方法重写为返回System.Threading.Tasks命名空间(MSDN reference)中的Task对象。通过这种方式,您可以启动后台处理来调用WCF服务,并使用Task的Result属性来确保服务已完成。
举个例子:
protected void Page_Load(object sender, EventArgs e)
{
    Task<string> t = Task<string>.Factory.StartNew(() =>
    {
        return MyWcfClientClass.StaticAsyncMethod(MyArguments);
    }

    /* other control initialization stuff here, while the task 
       and WCF call continue processing in background */

    /* Calling Result causes the thread to wait for the task to 
       complete as necessary, to ensure we have our correct value */
    MyLabel1.Text = t.Result;
}

好的,谢谢,我会尝试并按照您的建议去做!谢谢。 - George Taskos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接