4

我最近看到一个项目使用后台工作者进行一些操作(从其他 Web 服务获取数据)并使用事件将数据扔给客户端。该项目是一个 WCF 服务,由另一个类库作为 WCF 客户端角色由 ASP.NET 网站使用,并依次向应用程序抛出事件。这个全多线程系列让我好奇地研究。我已经看到这是一个basicHttpBinding绑定,服务的唯一行为是UseSynchronizationContext=false我发现他们在无法解释的异常之后添加了它,这是正常的:)

现在我问的ConcurrencyModebasicHttpBinding. 他们不应该这样做Reentrant还是这是默认行为?

如果 WCF 服务从客户端关闭,这种情况是否会继续失败,因为他们已经有一个未设置为对象实例的无法解释的引用?我相信在依赖 IIS 处理的 ASP.NET 项目消耗的 WCF 服务中使用多线程操作是不好的,因为在 WCF 服务将数据返回到客户端类库并将这些数据附加到页面之前,页面可能被发送到客户端。你能讨论以上问题并解释你的想法吗?

当您需要这种异步编程风格来通知 WCF 消费者在长时间操作后使用CallbackContracts嵌入式 WCF 技术而不是多线程操作时通知时,不应该更好吗?

需要澄清以纠正设计并证明这是一个糟糕的服务架构,如果它是真的,我怀疑!

谢谢你。

4

1 回答 1

2

它本质上并不是糟糕的架构,但听起来它确实造成了许多可能的陷阱。

WCF 客户端库将所有协调留给 ASP.NET 应用程序。如果 ASP.NET 应用程序未检查对 WCF 服务的调用是否已完成,则它可能会在使用服务中的值设置变量之前使用变量,以及其他此类竞争条件,除非明确设置某种协调方式针对完成事件的初始调用。

我的建议是重写 WCF 客户端异步方法以从命名空间(MSDN 参考)返回Task对象。通过这种方式,您可以剥离调用 WCF 服务的后台处理,并使用 的属性来确保服务已完成。System.Threading.TasksResultTask

一个例子:

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;
}
于 2012-05-02T20:38:39.773 回答