#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. Спасибо, что заметили это. Это из-за того, что я копирую код. 🙂