我想在与UI线程不同的线程上运行Allocate()函数。现在的问题是,当分配运行时,我的“忙碌指示器”冻结了。
<Window
x:Class="WpfApp4_test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp4_test"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
x:Name="MainWindow1"
Title="MainWindow"
Width="800"
Height="450"
Closing="MainWindow1_Closing"
mc:Ignorable="d">
<xctk:BusyIndicator x:Name="busyIndicator" IsBusy="True">
<xctk:BusyIndicator.ProgressBarStyle>
<Style TargetType="ProgressBar">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="Cyan" />
<Setter Property="Height" Value="15" />
<Setter Property="IsIndeterminate" Value="True" />
</Style>
</xctk:BusyIndicator.ProgressBarStyle>
<Grid x:Name="closing">
</Grid>
</xctk:BusyIndicator>
C#代码如下:
public partial class MainWindow : Window
{
public MainWindow()
{
BusyScope.BusyScopeChanged += this.BusyScope_BusyScopeChanged;
InitializeComponent();
this.busyIndicator.IsBusy = false;
}
private bool? myFucnt()
{
if (true)
{
MessageBoxResult result = MessageBox.Show(
this,
$"There are unsaved changes. Would you like to save them before proceeding",
"test",
MessageBoxButton.YesNoCancel,
MessageBoxImage.Warning,
MessageBoxResult.Cancel,
MessageBoxOptions.None);
if (result == MessageBoxResult.Cancel)
{
return null;
}
if (result == MessageBoxResult.Yes)
{
if (!this.fct1())
{
return false;
}
}
}
return true;
}
internal bool fct1()
{
try
{
this.Dispatcher.Invoke(
() =>
{
var message = "Save message";
MessageBox.Show("1", message, MessageBoxButton.OK, MessageBoxImage.Error);
});
this.Allocate();
return true;
}
catch (Exception)
{
var message = "There was an error saving the file. Please check that the data is valid and try again.";
MessageBox.Show("1", message, MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
}
private void Allocate()
{
int size = 0;
for (int z = 0; z < 100; z++)
{
for (int i = 0; i < 1000000; i++)
{
string value = i.ToString();
size += value.Length;
}
}
// Use bgWorker.ReportProgress(); to report the current progress
}
private void MainWindow1_Closing(object sender, CancelEventArgs e)
{
bool? temp = null;
BusyScope.IncrementBusyScope("closing");
temp = this.myFucnt();
if (temp != null)
{
Application.Current.Shutdown();
}
else
{
e.Cancel = true;
}
BusyScope.DecrementBusyScope();
}
}
要执行它,只需关闭应用程序(按“ x”按钮)。忙碌指示器冻结,因为关闭应用程序时正在运行长时间操作。繁忙指示器一直正常工作,直到它“击中” Allocate()函数为止(因为此函数执行需要花费大量时间)。
我尝试这种方法: https://www.dotnetperls.com/async
更新:
尝试了几次更改后,我完成了此修改
public partial class MainWindow : Window
{
public MainWindow()
{
BusyScope.BusyScopeChanged += this.BusyScope_BusyScopeChanged;
InitializeComponent();
this.busyIndicator.IsBusy = false;
}
private bool? myFucntAsync()
{
if (true)
{
MessageBoxResult result = MessageBoxResult.Cancel;
this.Dispatcher.Invoke(() =>
{
result = MessageBox.Show(
this,
$"There are unsaved changes. Would you like to save them before proceeding",
"test",
MessageBoxButton.YesNoCancel,
MessageBoxImage.Warning,
MessageBoxResult.Cancel,
MessageBoxOptions.None);
});
if (result == MessageBoxResult.Cancel)
{
return null;
}
if (result == MessageBoxResult.No)
{
return false;
}
if (result == MessageBoxResult.Yes)
{
bool t = this.fct1();
if (!t)
{
return false;
}
}
}
return true;
}
private bool fct1()
{
try
{
this.Allocate();
return true;
}
catch (Exception)
{
var message = "There was an error saving the file. Please check that the data is valid and try again.";
MessageBox.Show("1", message, MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
}
private void Allocate()
{
int size = 0;
for (int z = 0; z < 100; z++)
{
for (int i = 0; i < 100000; i++)
{
string value = i.ToString();
size += value.Length;
}
}
}
private async void MainWindow1_Closing(object sender, CancelEventArgs e)
{
bool? temp = null;
BusyScope.IncrementBusyScope("closing");
var firstLongTask = Task.Run(() =>
{
temp = this.myFucntAsync();
if (temp != false)
{
MessageBox.Show("done");
BusyScope.DecrementBusyScope();
this.Dispatcher.Invoke(() =>
{
Application.Current.Shutdown();
});
e.Cancel = false;
}
else
{
BusyScope.DecrementBusyScope();
e.Cancel = true;
}
return true;
});
var secondLongTask = Task.Run(() =>
{
e.Cancel = true;
return true;
});
var result = await Task.WhenAll(firstLongTask, secondLongTask);
}
}
通过这种方式,任务将执行this.myFucntAsync()
,之后
if (temp != false)
{
MessageBox.Show("done");
BusyScope.DecrementBusyScope();
this.Dispatcher.Invoke(() =>
{
Application.Current.Shutdown();
});
e.Cancel = false;
}
else
{
BusyScope.DecrementBusyScope();
e.Cancel = true;
}
但是由于应用程序错误关闭而仍然无法正常工作。