#c# #silverlight #wcf #callback #asynchronous
#c# #silverlight #wcf #обратный вызов #асинхронный
Вопрос:
Я работаю над этим проектом Silverlight 3.0, который полностью заполнен асинхронными вызовами веб-службы. На главной странице он извлекает некоторые необходимые данные для корректной работы приложения, используя 3 асинхронных вызова. Прямо сейчас приложение не отключает какие-либо элементы управления при выполнении этих вызовов, что означает, что пользователь может взаимодействовать с ним без этих необходимых данных. Мне нужно отключить всю сетку и только после завершения всех 3 асинхронных вызовов включить сетку.
Какова наилучшая практика для этого.
Это мои вызовы:
client.GetAllAsync();
client.GetAllCompleted = new EventHandler<GetAllCompletedEventArgs>(client_GetAllCompleted);
client.GetActualAsync();
client.GetActualCompleted = new EventHandler<GetActualCompletedEventArgs>(client_GetActualCompleted);
client.GetSomeAsync();
client.GetSomeCompleted = new EventHandler<GetSomeCompletedEventArgs>(client_GetSomeCompleted);
Ответ №1:
Кажется, слишком много работы только для того, чтобы поставить в очередь некоторую интерактивность пользователя.
Обычно я предоставляю интерфейс для всего приложения:
public interface IAppGlobalState
{
void BeginAsync();
void EndAsync();
}
В реализации я сделаю это:
public partial class MainShell : UserControl, IAppGlobalState
{
private int _queue;
private object _mutex = new Object();
public void BeginASync()
{
Monitor.Enter(_mutex);
if (_queue == 0)
{
VisualStateManager.GoToState(this, "BusyState", true);
}
Monitor.Exit(_mutex);
}
public void EndAsync()
{
Monitor.Enter(_mutex);
if (--_queue == 0)
{
VisualStateManager.GoToState(this, "IdleState", true);
}
Monitor.Exit(_mutex);
}
}
Конечно, если у вас тяжелая многопоточность, вы будете использовать Interlocked для них, но большую часть времени вы будете вызывать его из того же потока. Затем вы просто выполняете:
GlobalState.BeginAsync();
client.FirstAsyncCall();
GlobalState.BeginAsync();
client.FirstAsyncCall();
А затем при возврате просто:
GlobalState.EndAsync();
Если у вас есть вложенные вызовы, без проблем, этот метод их разматывает.
Ответ №2:
- Создайте единицу рабочего элемента в вашем silverlight
- Этот UOW вызывает событие по завершении
- Привяжите это событие к вашему коду GUI
- Используйте сигнализацию или простой счетчик в вашей рабочей единице, чтобы вызвать событие «завершено».