Multithreading Silverlight-在从方法返回之前等待异步调用完成

Multithreading Silverlight-在从方法返回之前等待异步调用完成,multithreading,silverlight,wcf,Multithreading,Silverlight,Wcf,我有一个Silverlight应用程序,它使用WCF服务,还使用Wintellect Power线程库来确保在应用程序继续之前逻辑完全执行。这是通过使用委托回调应用程序来实现的,这样它就可以在服务调用完全完成后继续 我希望在我的应用程序的另一部分中实现同样的效果,但不使用回调,例如,使用WCF服务的call方法表示从数据库加载对象,等待此返回,然后从调用的原始方法返回对象的Id 我能看到的唯一方法是在助手库中执行对WCF服务的调用,该库将对象加载到不同的线程上,原始方法将继续检查助手库(使用静态

我有一个Silverlight应用程序,它使用WCF服务,还使用Wintellect Power线程库来确保在应用程序继续之前逻辑完全执行。这是通过使用委托回调应用程序来实现的,这样它就可以在服务调用完全完成后继续

我希望在我的应用程序的另一部分中实现同样的效果,但不使用回调,例如,使用WCF服务的call方法表示从数据库加载对象,等待此返回,然后从调用的原始方法返回对象的Id

我能看到的唯一方法是在助手库中执行对WCF服务的调用,该库将对象加载到不同的线程上,原始方法将继续检查助手库(使用静态变量),等待它完成,然后返回它

这是实现此功能的最佳方式吗?如果是这样的话,下面是我的实现的详细信息,它不能正常工作

public class MyHelper
{

    private static Thread _thread;
    private static User _loadedObject;        

    public static GetUser()
    {
        return _loadedObject;
    }

    public static void LoadObject(int userId)
    {
        _loadedObject = null;
        ParameterizedThreadStart ts = new ParameterizedThreadStart(DoWork);           
        _thread = new Thread(ts);
        _thread.Start(userId);

    }

    private static void DoWork(object parameter)
    {            
        var ae = new AsyncEnumerator();
        ae.BeginExecute(DoWorkWorker(ae, Convert.ToInt32(parameter)), ae.EndExecute);    
    }

    private static IEnumerator<Int32> DoWorkWorker(AsyncEnumerator ae, int userId)
    {
        // Create a service using a helper method
        var service = ServiceHelper.GetService<IUserServiceAsync>();
        service.BeginGetUserById(userId, ae.End(), null);
        yield return 1;

        _loadedObject = service.EndGetUserById(ae.DequeueAsyncResult());
        _thread.Abort();
    }
}

对get The user的调用在helper方法中的不同线程上执行,但从未返回。这可能是由于产量和调用方法的休眠。我已经检查了获取用户在不同线程上的调用,因此我认为所有内容都应该分开,

我认为Silverlight应用程序对服务器的调用使用在UI线程上触发的事件;我认为这是浏览器中Silverlight主机环境的一部分,无法解决。因此,尝试从另一个线程回调服务器永远不会有好结果。如果您正在UI线程中的程序代码中等待,您将永远无法从WCF调用中获取调用结果事件


可以使用UI线程上的回调模拟来自非UI线程的同步调用,但这可能不是您想要的。最好咬紧牙关,让程序逻辑与Silverlight提供的异步调用一起工作。

您使用的整个构造与Silverlight当前的最佳实践不匹配。在Silverlight中,数据访问方法(当然是通过Web服务)是异步执行的。您不应该围绕这一点进行设计,而是相应地调整您的设计


但是,在某些情况下,顺序调用服务(与同步调用不同)是有效的。在中,我展示了如何通过订阅远程调用的已完成事件并同时阻止UI来实现这一点,工作流看起来和感觉上都像普通的异步调用。

如果您针对为服务引用创建的接口进行编码,您可以为每个服务调用“同步”调用
Begin
End
方法,然后,我们传入一个
操作
,在
结束
方法完成后执行。请注意,您必须从调度程序执行此操作。这非常接近于进行同步调用,因为在调用仍在进行的地方写入调用后要运行的代码,并且在服务调用完成后执行。不过,它确实涉及到创建包装器方法,但我们也通过隐藏包装器并自动生成包装器来解决这一问题。看起来需要做很多工作,但实际上并非如此,而且最终比所有事件处理程序都要优雅。如果您需要有关此模式的更多信息,请告诉我

我同意,并且我的应用程序遵循最佳实践。这个问题是在试验和打破这些做法。这个问题是一个场景的一部分,在这个场景中,我想调用一个方法,该方法为了计算其结果,必须调用许多方法,所有这些方法都可以异步服务,然后返回一个计算值。在被调用方获得这个值之后,它可能需要在同一个文件中选择性地执行另一个方法,以此类推。考虑到要处理的回调/事件的数量,我正在寻找尽可能简单地编写此场景的方法。
public int GetUser(int userId)
{
    MyHelper.LoadObject(userId);
    User user = MyHelper.GetUser();
    while (user == null)
    {
        Thread.Sleep(1000);
        user = MyHelper.GetUser();
    }
    return user.Id;
 }