gpt4 book ai didi

c# - 窗口关闭事件中的 Threading.task 和 Dispatcher.Invoke 方法

转载 作者:行者123 更新时间:2023-12-03 10:16:14 26 4
gpt4 key购买 nike

我想在关闭基于 MVVM 的 WPF 应用程序时同步执行一系列操作。

现在我在任务中使用 Task 和 Dispatcher.Invoke 向用户显示消息。

问题是,当我在 myfunction 函数中使用 Dispatcher.Invoke 方法时,应用程序会卡在那里。当我使用关闭事件以外的这些功能时,我知道该功能正常工作。

那么在应用程序的 Close 事件中使用 Dispatcher.Invoke 方法是否存在任何问题。我该如何解决这个问题?

/// <summary>
/// Main window closing
/// </summary>
private void MainWindowClosing(object args)
{
var task1 = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
myfunction();
}).ContinueWith((cc) => { });
task1.Wait();
}

private void myfunction()
{
//my serries of operation will come here.
System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
{
MessageBox.Show("test");
}));
}

最佳答案

您正在创建一个Deadlock这里。即使将代码放入按钮单击处理程序中,它也不会工作。

原因

您正在使用 task1.Wait() 创建任务并等待任务。因此,UI 调度程序正在等待任务完成,然后才能处理任何进一步的消息。

同时,您从任务调用 UI 调度程序上的一个操作,这里也是同步的

        App.Current.Dispatcher.Invoke(new Action(() =>
{
MessageBox.Show("test");
}));

但由于 UI 调度程序仍在等待任务完成,因此您无法在其上同步调用任何方法。因此出现了DEADLOCK(互相等待)。

可能的解决方案

如果你想在不关闭窗口的情况下同步调用任务,你可以使用以下步骤实现:

  1. 首先删除task1.Wait()。 (不要阻止 UI 调度程序)
  2. 其次,维护 bool 以保持关闭事件已启动的计数。
  3. 最后,通过设置 e.Cancel = true 取消关闭事件,并在完成后手动从任务本身引发关闭事件。

相关代码:

    bool closeInitiated = false;
private void poc_Closing(object sender, CancelEventArgs e)
{
if (!closeInitiated)
{
var task1 = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
myfunction();
}).ContinueWith((cc) => { });
closeInitiated = true;
e.Cancel = true;
}
}

private void myfunction()
{
App.Current.Dispatcher.Invoke(new Action(() =>
{
MessageBox.Show("test");
Close();
}));
}

关于c# - 窗口关闭事件中的 Threading.task 和 Dispatcher.Invoke 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20918311/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com