Вызов асинхронного метода несколько раз - PullRequest
1 голос
/ 15 марта 2011

Я вызываю асинхронный метод с одним параметром, Он вернет мне результат в соответствии с параметром. Я вызываю этот метод более одного раза с другим значением параметра, но в событии 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 ]

2 голосов
/ 05 мая 2011

Получен ответ Ваш метод может возвращать другое значение на основе первого параметра, но оба обработчика будут вызываться в одно и то же время каждый раз, независимо от того, что вы отправили.Если это стандартная ссылка на веб-сервис, вы должны увидеть доступный для вас параметр 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 голос
/ 15 марта 2011

Вы должны либо добавить обработчик событий только один раз и передать обратно тип данных, извлеченных в объекте 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;
}

В этом случае вам необходимо изменить код вашего серверного кода, чтобы он соответствовал.

0 голосов
/ 15 марта 2011

без исходного кода, немного сложно угадать проблему, но я думаю, что проблема в том, что вы добавляете один и тот же завершенный обработчик несколько раз. Как это:

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
    }

Это может решить вашу проблему.

Вот еще несколько идей: Поскольку ваш вызов асинхронный, может случиться так, что завершенный обработчик вызывается до десяти раз для каждого вызова (потому что вы добавили его 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
}
    }

Проблема здесь в том, что вам нужна какая-то переменная класса для отслеживания ваших пользовательских состояний. Если вы напишите это так, вам не нужно это делать.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...