Кажется, много работы только для того, чтобы поставить в очередь интерактивность пользователя.
Обычно я предоставляю интерфейс для всего приложения:
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();
Если у вас есть вложенные вызовы, нет проблем, этот метод их раскручивает.