多次调用异步方法

时间:2011-03-15 10:57:11

标签: silverlight

我正在调用具有单个参数的异步方法, 它会根据参数返回结果。 我用不同的参数值多次调用该方法,但在Completed事件中,我获得了相同的值。

client.ListAllLookupValuesByTypeCompleted += client_ListAllAddressFormatCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat");

client.ListAllLookupValuesByTypeCompleted += client_ListAllPhoneFormatCompleted;
client.ListAllLookupValuesByTypeAsync("PhoneFormat");



void client_ListAllAddressFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
        {
            cmbAddressFormat.ItemsSource = e.Result;
        }


void client_ListAllPhoneFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
        {
            cmbPhonePrintFormat.ItemsSource = e.Result;
        }

任何建议。 感谢。

3 个答案:

答案 0 :(得分:2)

得到了答案 您的方法可能会根据第一个参数返回不同的值,但每次都会同时调用这两个处理程序,无论您发送的是什么。如果这是一个标准的Web服务引用,那么您应该看到一个对象userState参数可供您使用,这可用于确定要执行的操作。

client.ListAllLookupValuesByTypeCompleted += client_ListAllLookupValuesCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat", true);
client.ListAllLookupValuesByTypeAsync("PhoneFormat", false);



void client_ListAllLookupValuesCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
        {
            // e.UserState will either be false or true
            if ((bool)e.UserState)
               cmbAddressFormat.ItemsSource = e.Result;
            else
               cmbPhonePrintFormat.ItemsSource = e.Result;
        }

答案 1 :(得分:1)

您应该只添加一次已完成的事件处理程序并传回ListAllLookupValuesByTypeCompletedEventArgs对象中检索到的数据类型:

client.ListAllLookupValuesByTypeCompleted += client_ListFormatCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat");
client.ListAllLookupValuesByTypeAsync("PhoneFormat");

void client_ListFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
    if (e.Type == ResultType.AddressFormat)
    {
        cmbAddressFormat.ItemsSource = e.Result;
    }
    else
    {
        cmbPhonePrintFormat.ItemsSource = e.Result;
    }
}

或为每种数据类型分别设置两个事件:

client.ListAddressLookupValuesCompleted += client_ListAddressFormatCompleted;
client.ListAddressLookupValuesAsync();

client.ListPhoneLookupValuesCompleted += client_ListPhoneFormatCompleted;
client.ListPhoneLookupValuesByTypeAsync();

void client_ListAddressFormatCompleted(object sender, ListAddressValuesCompletedEventArgs e)
{
    cmbAddressFormat.ItemsSource = e.Result;
}

void client_ListPhoneFormatCompleted(object sender, ListPhoneValuesCompletedEventArgs e)
{
    cmbPhonePrintFormat.ItemsSource = e.Result;
}

在这种情况下,您需要重构服务器端代码才能匹配。

答案 2 :(得分:0)

没有源代码,有点难以猜测问题,但我认为问题是,您多次添加相同的已完成处理程序。像这样:

for(int i =0; i < 10; i++)
{
  ws.callCompleted += CallCompletedHandler;
  ws.callAsync(i);
}

void CallCompletedHandler(object sender, EventArgs args) 
{
  handle result
}

您是否在已完成的事件中删除了处理程序?

 void CallCompletedHandler(object sender, EventArgs args) 
    {
     ws.callCompleted -= CallCompletedHandler;
      handle result
    }

这可以解决您的问题。

以下是其他一些想法: 当您调用isync时,可能是您完成的处理程序每​​次调用最多调用十次(因为您将其添加了10次)。您可以使用UserState参数(http://msdn.microsoft.com/en-us/library/wewwczdw(v=vs.80).aspx),这样您就可以将已完成的处理程序与您的呼叫进行匹配。

for(int i =0; i < 10; i++)
    {
      ws.callCompleted += CallCompletedHandler;
      ws.callAsync(i, i); //Second param is user state
    }

    void CallCompletedHandler(object sender, EventArgs args) 
    {
      if(args.UserState == //Your check here;)
{
      ws.callCompleted -= CallCompletedHandler; //Remove the handler
      handle result
}
    }

这里的问题是,您需要某种类变量来跟踪您的UserStates。 如果你这样写,你不必这样做。

for(int i =0; i < 10; i++)
        {
          CallWebservice(i);

        }

        void CallWebservice(int i)
        {
          EventHandler myHandler= null;
          myHandler = (s, args) => {
          if(args.UserState == i){
            ws.callCompleted -= myHandler; //Remiov
            Handleresult
          };
          ws.callCompleted += myHandler; //Add the handler
          ws.callAsync(i, i); //Call the ws
        }
     }

如果您有任何其他问题,请发表评论。如果您能提供一些源代码,我想我们可以为您提供更多帮助。

BR,

TJ