C# Silverlight和对WCF的同步调用

C# Silverlight和对WCF的同步调用,c#,silverlight,wcf,C#,Silverlight,Wcf,我已经知道通过Silverlight对WCF服务的调用是异步的。我还知道,许多人出于各种愚蠢的原因(例如阻止UI线程)试图找到让他们同步调用的方法,通常应该像瘟疫一样避免这样的事情 我只想自己处理所有的线程,因为我发现必须钩住/解开所有的“*Completed”事件是一项额外的工作,也是一种巨大的痛苦,特别是当您不知道调用的顺序等时。有人知道一种聪明的方法来进行同步调用并自己执行线程吗?如果您将调用包装到另一个函数中,该函数将一直休眠,直到异步调用返回吗?如果您不应该进行同步网络调用,您不应该进

我已经知道通过Silverlight对WCF服务的调用是异步的。我还知道,许多人出于各种愚蠢的原因(例如阻止UI线程)试图找到让他们同步调用的方法,通常应该像瘟疫一样避免这样的事情


我只想自己处理所有的线程,因为我发现必须钩住/解开所有的“*Completed”事件是一项额外的工作,也是一种巨大的痛苦,特别是当您不知道调用的顺序等时。有人知道一种聪明的方法来进行同步调用并自己执行线程吗?

如果您将调用包装到另一个函数中,该函数将一直休眠,直到异步调用返回吗?

如果您不应该进行同步网络调用,您不应该进行同步网络调用,也不应该进行同步网络调用,如果您真的、真的知道自己在做什么,那么您实际上可以进行同步(阻塞)调用,前提是您不在UI线程中。。要知道这不是一个官方支持的场景(因此它没有其他功能那样经过测试),但我已经尝试过几次了,它确实有效

您需要做的就是使用
[ServiceContract]
接口(而不是客户机类)——公开开始/结束操作的接口——并调用
EndXXX(BeginXXX(parameters,null,null))
,如下例所示(这是一个包含两个控件的页面,一个
按钮
,其
点击
事件绑定到
按钮点击
处理程序,以及一个名为“txtDebug”的
文本框
,代码在其中写入结果

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.AddToDebug("In Button_Click");
        ThreadPool.QueueUserWorkItem(delegate
        {
            ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
            ServiceReference1.Service1 asInterface = client;
            this.AddToDebug("Calling server \"synchronously\"...");
            int result = asInterface.EndAdd(asInterface.BeginAdd(45, 67, null, null));
            this.AddToDebug("Result: {0}", result);
            client.CloseAsync();
        });
    }

    private void AddToDebug(string text, params object[] args)
    {
        if (args != null && args.Length > 0)
        {
            text = string.Format(text, args);
        }

        text = string.Format("[{0} - {1}] {2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("HH:mm:ss.fff"), text);

        this.Dispatcher.BeginInvoke(() => this.txtDebug.Text = this.txtDebug.Text + text + Environment.NewLine);
    }
}

现在,如果您想从UI线程执行此操作,那么实际上,没有办法阻止并等待响应(因为响应也应该在UI线程上返回)。如果您能适应开始/结束模式,您仍然可以执行异步调用,但不必担心事件处理程序被泄漏。

依赖于阻止线程(任何线程,而不仅仅是UI线程)的解决方案线程是昂贵的资源,而线程池线程是有限的资源。这就是为什么网络API首先具有回调语义的原因

我同意Carlos的观点,首先要做的是切换到该服务提供的.NET异步模式接口,而不是可怕的基于事件的接口。(基于事件的方法旨在使“考虑事件”的UI开发人员能够简化工作。)如果您的服务被称为“Service1”,那么您的客户端类将被调用“Service1Client”。不过,该类还将支持名为“Service1”的接口,该接口将具有OperationContracts的开始/结束版本

“一种进行同步调用的聪明方法”

如果不阻塞线程,这是不可能的。但是,使一系列任务同步并不是真正的要求。我们想要的只是确保一系列任务以顺序发生。您可以通过从上一个任务的回调方法调用下一个任务来实现这一点,但是嵌套变得有点困难莱姆


请看一看这一系列,可能从上一篇开始。不幸的是,WCF文章仍在进行中,但我真的必须尽快将其发布,这些东西经常出现在这里。

为什么要取消所有
已完成的事件的挂钩?以避免内存泄漏。在短期服务中,可以在多个位置调用“a”,有时,它的“已完成”事件没有完全相同的处理程序。但让我们避免讨论设计/意图,并坚持问题的技术部分……这很公平,但知道设计/意图会影响解决方案。同意。问题是我可以想出几十个更长的解决方案,并自己处理线程uld最好。-->简言之,我正在尝试将服务调用+结果设置为单个协程,但生成的所有其他类型都让这成为一个巨大的难题。反射工作正常,但仍然非常冗长,然后还有整个性能问题……您是否尝试了Rx而不是尝试进行同步?基本上是这样我现在正在做的是,但它仍然无法避免挂起/取消挂起事件的代码开销。是的,我永远不想阻止UI线程,只想避免“正常”Silverlight方法的开销。这看起来将把我带向正确的方向…你真的在Silverlight中尝试过吗?因为Silverlight不支持在IAsyncResult的实现上使用AsyncWaitHandles,很难看出它是如何工作的?我并不是说它绝对不工作,我自己也没有尝试过,但如果它真的尝试过,我会感到非常惊讶。是的,我在回答之前尝试过。正如我所说,它不受支持,但在简单的情况下我尝试过它,所以它“使用风险自负”“黑客,明白了。我想黑客有时是不可避免的。”