尽我们所知, 程序正在逐行执行,现在我面临问题,我有一个方法,需要几秒钟才能执行, 我以为我可以通过线程解决它,但我稍后会谈到它,现在我想做的是下一步:
当该方法开始执行并且方法完成时,我怎么能打开一个窗口,其中包含“仍在执行......”之类的消息,窗口可以关闭自己, 我需要这个,因为我想避免UI冻结,因为那个长方法不在另一个任务/线程中。
以下是它的样子:
if (e.Key == Key.Delete)
{
//Could I show window here like like "Loading please wait.."
ExecuteLongMethod();
//When this is done close this method
}
谢谢你们, 干杯
答案 0 :(得分:3)
如果由于某种原因必须在调度程序线程上执行ExecuteLongMethod()
,则可以创建一个新窗口,该窗口在单独的线程中启动,并在长时间运行的方法完成所需的时间内显示该窗口。有关更多信息,请参阅以下链接。
Wait screen during rendering UIElement in WPF
另一个选项是在后台线程上执行长时间运行的方法,并在主线程上显示加载窗口。
建议的方法是使用任务并行库(TPL)并启动任务:https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx
if (e.Key == Key.Delete)
{
Window window = new Window();
window.Show();
Task.Factory.StartNew(() => ExecuteLongMethod())
.ContinueWith(task =>
{
window.Close();
},System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
答案 1 :(得分:0)
显示顶部窗口/控件并显示进度信息并禁用主窗口的示例:
if (e.Key == Key.Delete)
{
// create a window with a progress ring or progress bar
var window = new Window();
new Thread(() =>
{
// execute long method
ExecuteLongMethod();
// close the progress window - release control
// ensure it is done on the UI thread
System.Windows.Application.Current.Dispatcher.Invoke(() => window.Close());
}).Start();
// display progress window
window.ShowDialog();
}
另一种方法是暂时禁用或隐藏任何可能干扰后台线程且不阻塞主窗口的UI元素(按钮,制表符)。
答案 2 :(得分:0)
使用await-pattern
public void YourMethod()
{
if (e.Key == Key.Delete)
{
//Could I show window here like like "Loading please wait.."
FireAndForget();
//When this is done close this method
}
}
public async void FireAndForget()
{
await Task.Run(() => { ExecuteLongMethod(); });
}
火灾和遗忘是一种反模式,但有时你会面临无法等待的问题 - 例如Commands
。
如果你想等待一个结果,或者直到结束就像这样
public async void YourMethodAsync()
{
if (e.Key == Key.Delete)
{
//Could I show window here like like "Loading please wait.."
await CorrectWayAsync();
//When this is done close this method
}
}
public async Task CorrectWayAsync()
{
await Task.Run(() => { ExecuteLongMethod(); });
}