如何在使用 Dispatcher 的 Backgroundworker 时访问 UI 元素?
How can I access UI element while Backgroundworker with Dispatcher?
enter image description here 我知道这不是关于访问 UI 线程的第一个问题,但我没有找到解决我问题的答案。
在调用示例方法时,它会像带有中止的消息框一样显示 button.If 我单击中止按钮,它将不会点击中止按钮 event.Here 警报框 UI 是 freezing.So我们打不到那个。
如果我删除调度程序行,它将起作用 fine.But 我希望该行用于执行 AddQueryIntoTable 方法。如果该方法将在 100 毫秒后调用,它将完美地检索数据。
所以我将设置 100 毫秒作为睡眠模式(注释行)它会起作用 fine.But 我认为这不是完美的解决方案。
提前致谢。
public void SampleMethod()
{
CancelSupportedBackgroundWorker backGroundWorker = new CancelSupportedBackgroundWorker { WorkerSupportsCancellation = true };
CancellationTokenSource source = new CancellationTokenSource();
AlertBox alertBox = new AlertBox
{
WaitingText = "Loading Indicator",
WaitingHeaderText = "It is Loading",
};
alertBox.IsBusy = true;
alertBox.AbortButton.Click += (obje, arg) =>
{
MessageBox.Show("Hit");
};
backGroundWorker.DoWork += (obj, e) =>
{
App.Current.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(
delegate ()
{
try
{
if (info == null)
{
//Thread.sleep(100);
arg.result = AddqueryintoTable((CancellationToken)e.Argument);
if (backGroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}
}
catch (ThreadAbortException)
{
Dispatcher.Invoke(() =>
{
alertBox.IsBusy = false;
}, System.Windows.Threading.DispatcherPriority.Background);
e.Cancel = true;
}
}));
};
backGroundWorker.RunWorkerCompleted += (obj, arg) =>
{
if (arg.Cancelled)
{
alertBox.IsBusy = false;
return;
}
alertBox.IsBusy = false;
if (arg != null && arg.Result != null)
{
SetReport(arg.Result);
}
};
backGroundWorker.RunWorkerAsync(source.Token);
}
尽量不要将整个 DoWork
方法放在 Dispatcher 调用中,而是只调用其中的一个操作。
backGroundWorker.DoWork += (obj, e) =>
{
try
{
if (info == null)
{
Thread.Sleep(100);
App.Current.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action( delegate ()
{
arg.result = AddqueryintoTable((CancellationToken)e.Argument);
}));
if (backGroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}
}
catch (ThreadAbortException)
{
Dispatcher.Invoke(() =>
{
alertBox.IsBusy = false;
}, System.Windows.Threading.DispatcherPriority.Background);
e.Cancel = true;
}
};
enter image description here 我知道这不是关于访问 UI 线程的第一个问题,但我没有找到解决我问题的答案。
在调用示例方法时,它会像带有中止的消息框一样显示 button.If 我单击中止按钮,它将不会点击中止按钮 event.Here 警报框 UI 是 freezing.So我们打不到那个。
如果我删除调度程序行,它将起作用 fine.But 我希望该行用于执行 AddQueryIntoTable 方法。如果该方法将在 100 毫秒后调用,它将完美地检索数据。
所以我将设置 100 毫秒作为睡眠模式(注释行)它会起作用 fine.But 我认为这不是完美的解决方案。
提前致谢。
public void SampleMethod()
{
CancelSupportedBackgroundWorker backGroundWorker = new CancelSupportedBackgroundWorker { WorkerSupportsCancellation = true };
CancellationTokenSource source = new CancellationTokenSource();
AlertBox alertBox = new AlertBox
{
WaitingText = "Loading Indicator",
WaitingHeaderText = "It is Loading",
};
alertBox.IsBusy = true;
alertBox.AbortButton.Click += (obje, arg) =>
{
MessageBox.Show("Hit");
};
backGroundWorker.DoWork += (obj, e) =>
{
App.Current.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(
delegate ()
{
try
{
if (info == null)
{
//Thread.sleep(100);
arg.result = AddqueryintoTable((CancellationToken)e.Argument);
if (backGroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}
}
catch (ThreadAbortException)
{
Dispatcher.Invoke(() =>
{
alertBox.IsBusy = false;
}, System.Windows.Threading.DispatcherPriority.Background);
e.Cancel = true;
}
}));
};
backGroundWorker.RunWorkerCompleted += (obj, arg) =>
{
if (arg.Cancelled)
{
alertBox.IsBusy = false;
return;
}
alertBox.IsBusy = false;
if (arg != null && arg.Result != null)
{
SetReport(arg.Result);
}
};
backGroundWorker.RunWorkerAsync(source.Token);
}
尽量不要将整个 DoWork
方法放在 Dispatcher 调用中,而是只调用其中的一个操作。
backGroundWorker.DoWork += (obj, e) =>
{
try
{
if (info == null)
{
Thread.Sleep(100);
App.Current.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action( delegate ()
{
arg.result = AddqueryintoTable((CancellationToken)e.Argument);
}));
if (backGroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}
}
catch (ThreadAbortException)
{
Dispatcher.Invoke(() =>
{
alertBox.IsBusy = false;
}, System.Windows.Threading.DispatcherPriority.Background);
e.Cancel = true;
}
};