Я предложу окно "BusyDialog" в дополнение к фоновой теме.
Диалоговое окно «занят» может быть анимацией, показывающей, что он что-то делает, и также модально блокирующей любой пользовательский ввод.
public partial class BusyDialog : Window
{
public BusyDialog()
{
InitializeComponent();
}
public static T Execute<T>(DependencyObject parent, Func<T> action)
{
Window parentWindow = null;
if (parent is Window)
{
parentWindow = parent as Window;
}
else
{
parentWindow = Window.GetWindow(parent);
}
T val = default(T);
Exception le = null;
BusyDialog bd = new BusyDialog();
bd.Owner = parentWindow;
ThreadPool.QueueUserWorkItem((o) =>
{
try
{
val = action();
}
catch (Exception ex)
{
le = ex;
}
bd.EndDialog();
});
bd.ShowDialog();
if (le != null)
{
Trace.WriteLine(le.ToString());
throw new Exception("Execute Exception", le);
}
return val;
}
private void EndDialog()
{
Dispatcher.Invoke((Action)delegate() {
this.DialogResult = true;
});
}
}
Теперь вы можете использовать следующий способ для асинхронного вызова вашего метода,
List<Result> results = BusyDialog.Execute( this ,
()=>{
return MyLongDatabaseLoadingCall();
});
Вот что происходит,
- BusyDialog отображается модально, блокируя любой пользовательский ввод, а также отображая занятую анимацию
- Вызов вашего метода MyLongDatabaseLoadingCall выполняется в ThreadPool.QueueUserItem, который асинхронно вызывает ваш метод в другом потоке (то же самое, что и функция фоновой многопоточности, предложенная другими здесь).
- Анимация продолжается до выполнения вызова
- Когда ваш метод заканчивается, BusyDialog заканчивается, и все возвращается к тому, что было.