繁体   English   中英

在C#中调用showdialog时出现Threadabortexception

[英]Threadabortexception when calling showdialog in C#

我有一个应用程序,它解析一个大的XML文件,并根据该内容构建WPF UI控件。 此任务通常需要大约15 - 30秒。 为了通知用户正在运行的任务,我显示了一个简单的中间进度对话窗口,如:

Thread progressDialogThread = new Thread(() =>
{
    Window window = new Window
    {
        Content = new ProgressDialog(),
        Height = 100,
        Width = 150,
        WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen
    };
    window.ShowDialog();
});

progressDialogThread.SetApartmentState(ApartmentState.STA);
progressDialogThread.IsBackground = true;
progressDialogThread.Start();

buildUI();

progressDialogThread.Abort();

这很有效,但是当我再次解析XML时,我有时会在progressDialogThread.Start()上获得ThreadAbortException。

有没有人知道更好的方法来“关闭”进度对话框?

由于控件必须在主UI线程上构建,我不能使用backgroundworker ...

XAML中的进度对话框本身如下所示:

<UserControl x:Class="MyDialog.ProgressDialog"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyDialog"
        mc:Ignorable="d"
        Background="{DynamicResource MaterialDesignPaper}"
        TextElement.Foreground="{DynamicResource MaterialDesignBody}"
        Height="100" Width="150">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <Label HorizontalAlignment="Center">Please wait</Label>
        <ProgressBar
          Style="{StaticResource MaterialDesignCircularProgressBar}"
          Value="0"
          IsIndeterminate="True" Width="40" Height="41" Margin="55,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </StackPanel>
</UserControl>

不要中止线程,应该避免。

如果要关闭Window ,请在其上调用Close

哦,它是由另一个线程创建的? 好吧,这就是为什么Window有一个Dispatcher ,你使用BeginInvoke ,它将在该线程上运行回调。

事实上,你有可能不需要在另一个线程※创建Window 您可以在主线程中创建它,并让后台线程通过BeginInvoke与它进行交互。

※:如果您的主线程忙,并希望Window在另一个线程中,因此主线程不会阻止它(或反之亦然),您可能应该使用BackgroundWorker (如Caius Jard建议的那样 ),而不是让UI线程忙。

像这样的东西正是BackgroundWorker的用途,也是为什么它知道UI线程和工作线程之间的区别。 使用后台工作程序,在DoWork事件处理程序中解析XML文件(它将在后台线程上运行),并在继续DoWork循环时使用ReportProgress方法定期报告进度。 ProgressChanged处理程序代码将在UI线程上执行,它应该戳进度对话框以提供进程的状态更新

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM