簡體   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