Можно ли отредактировать следующий код, чтобы второй метод тоже выполнялся?

#c#

#c#

Вопрос:

Можно ли каким-либо образом вызвать methodB до завершения methodA, чтобы methodB был выполнен? Я перепробовал множество способов его реализации, и ни один из них не сработал : (


кто-нибудь может объяснить? Спасибо.

 public List<ObjectA> _OurObjectA= new List<ObjectA>();

public  List<ObjectA> methodA()
{

    List<ObjectA> products = new List<ObjectA>();
    ServiceReference1.ServiceClient client = 
      new ServiceReference1.ServiceClient();
    client.getProductCompleted  = 
      new EventHandler<ServiceReference1.getProductCompletedEventArgs>(methodB);

    client.getProductAsync();

    return _OurObjectA;
}

void methodB(object sender, ServiceReference1.getProductCompletedEventArgs e)
{
    ObservableCollection<ServiceReference1.ObjectA> products = e.Resu<
    foreach (ServiceReference1.ObjectA obj in products)
    {
        ObjectA temp = new ObjectA(obj);
        _OurObjectA.Add(temp);
    }
}
  

Ответ №1:

Похоже, что methodA вызывает веб-службу. Когда веб-служба завершена, она вызывает methodB. Запутанная часть заключается в том, что это асинхронно (через обработчик событий)… methodA возвращается сразу; ему не нужно ждать завершения работы веб-службы.

Вероятно, это было сделано потому, что служба занимает много времени (условно говоря), поэтому в этом случае вы можете сразу вернуться из methodA, выполнить какую-то другую работу, а когда веб-служба будет завершена, methodB сможет выполнить это с данными, возвращенными из веб-службы. Это более эффективное использование ресурсов. Иногда подобные вещи делаются для того, чтобы пользовательский интерфейс не выглядел так, как будто он «завис».

Комментарии:

1. Большое спасибо. Да, это приложение silverlight со службой WCF. Методb, похоже, никогда не выполняется, когда я запускаю этот код, он просто пропускает часть, а затем браузер выдает ошибку, и все приложение, я думаю, это потому, что оно асинхронное? Есть ли какие-либо способы исправить это? Спасибо 🙂

Ответ №2:

У вашего клиентского объекта есть событие, называемое getProductCompleted. Когда это событие публикуется, выполняется methodB. client.getProductAsync() — это асинхронный вызов, означающий, что он начнет загрузку продукта в фоновом режиме, даже если метод вернется немедленно. Когда загрузка продукта завершена, клиент публикует событие, вызывающее выполнение methodB.

Комментарии:

1. Спасибо! Я понял, что methodB вызывается только после завершения работы службы, а к тому времени уже слишком поздно, браузер уже закончил загрузку информации. : (

Ответ №3:

Он назначает метод methodB в качестве обработчика события для события getProductCompleted . Когда событие вызывается client переменной, выполняется обработчик события.

Обновить:
Я обновляю свой ответ, чтобы фактически ответить на ваш вопрос…
Вы можете использовать этот код для возврата из methodA после возврата продуктов:

 public  List<ObjectA> methodA()
{
    var products = new List<ObjectA>();
    var mre = new ManualResetEvent(false);
    var client = new ServiceReference1.ServiceClient();
    client.getProductCompleted  = (s, e) => {
                                               try
                                               {
                                                   products.AddRange(
                                                       e.Result.Select(o => 
                                                            new ObjectA(o)));
                                               }
                                               finally
                                               {
                                                   mre.Set();
                                               }
                                            };

    client.getProductAsync();
    mre.WaitOne();

    return products;
}
  

В этом случае вам даже не нужен methodB.
Код предполагает, что вы используете по крайней мере .NET 3.5.

Комментарии:

1. Спасибо за редактирование моего кода 🙂 Итак, я предполагаю, что если вызывается methodA, то он автоматически вызывает methodB? Но почему-то он не вызывается. Можно ли как-нибудь объединить эти 2 метода (в 1 метод)? Спасибо 🙂

2. Методb будет вызываться только при возникновении события. Как объясняет Джованни, это происходит после того, как веб-сервис завершил свою работу. Это может произойти спустя много времени после завершения выполнения метода.

3. о … спасибо. Есть ли какие-либо способы исправить это? Поскольку я хочу вернуть список объектов после завершения метода A 🙂

4. @Rosie: Принимать ответ до того, как ваша проблема будет решена, не очень хорошая идея, потому что это отбивает у людей охоту и дальше помогать вам…

5. О, вы правы. спасибо, что указали на это 🙂 Я перепробовал несколько способов его реализации, ни один из них, похоже, не работает. У вас есть какие-нибудь идеи?

Ответ №4:

И, по-видимому, в methodB есть ошибка:

  foreach (ServiceReference1.ObjectA obj in products)
    {
        ObjectAtemp = new ObjectA(obj);
         // no temp -- there should be a space between ObjectA and temp in the line above
         // perhaps just a typo here on SO? or in the original code?
         // EDIT: I see the code in methodB has now been corrected.
         _OurObjectA.Add(temp);
    }
  

Комментарии:

1. Спасибо, что заметили это. Это из-за того, что я копирую код. 🙂