2009-11-11 45 views
0

对于从silverlight 3调用wcf服务并更新单独线程中的ui的场景中的事件排序,我有一个问题。基本上,我想知道我在做什么是正确的...示例如下。这是我在这里的第一篇文章,请耐心等待,因为我不确定如何发布实际代码。示例如下:来自Silverlight 3的异步Web服务调用

//<summary> 
public static void Load(string userId) 
{ 

    //Build the request. 
    GetUserNameRequest request = 
    new GetUserNameRequest { UserId = userId }; 

    //Open the connection. 
    instance.serviceClient = ServiceController.UserService; 

    //Make the request. 
    instance.serviceClient.GetUserNameCompleted 
    += UserService_GetUserNameCompleted; 

    instance.serviceClient.GetGetUserNameAsync(request); 

    return instance.VM; 
} 

/// <summary> 
private static void UserService_GetUserNameCompleted(object sender, GetUserNameCompletedEventArgs e) 
{ 
    try 
    { 
    Controller.UIDispatcher.BeginInvoke(() => 
    { 
     //Load the response. 
     if (e.Result != null && e.Result.Success) 
     { 
     LoadResponse(e.Result); 
     } 

     //Completed loading data. 
    }); 
    } 
    finally 
    { 
    instance.serviceClient.GetUserNameCompleted 
     -= UserService_GetUserNameCompleted; 

    ServiceHelper.CloseService(instance.serviceClient); 
    } 
} 

所以我的问题主要是,我的UI线程内,当我加载的响应,如果抛出异常,将在“最后”块明白了吗?如果没有,我应该在另一个try/catch里面加载响应的lambda?

另外,因为我在ui线程上执行加载,是否有可能在UI线程完成更新之前执行finally操作?并且可能因此在加载完成之前调用Servicehelper.CloseService()?

我问,因为我使用这种方法有间歇性问题。

回答

0

finally块应在之前执行处理BeginInvoke中的响应。 BeginInvoke意味着代码将在下一个UI周期中执行。

通常,这种类型的最佳方法是将所需的所有数据从响应中提取出来并存储在变量中,然后清理服务代码。然后调用BeginInvoke并使用变量中的数据更新UI。