C# 线程传递数据和窗口关闭

C# 线程传递数据和窗口关闭,c#,wpf,multithreading,excel,C#,Wpf,Multithreading,Excel,我已经创建了一个简单的WPF项目,在这个项目中,我单击按钮创建一个带有新窗口的独立线程,并将数据传递给它。在应用程序退出时,我正在尝试安全地关闭该线程/窗口。但是,我偶尔会遇到下面的异常,这会导致应用程序不稳定。 所以我的问题是如何优雅地处理这种情况。Thx 在线: Dispatcher.Invoke(new Action(() => 我有 A first chance exception of type 'System.Threading.ThreadAbortException'

我已经创建了一个简单的WPF项目,在这个项目中,我单击按钮创建一个带有新窗口的独立线程,并将数据传递给它。在应用程序退出时,我正在尝试安全地关闭该线程/窗口。但是,我偶尔会遇到下面的异常,这会导致应用程序不稳定。
所以我的问题是如何优雅地处理这种情况。Thx

在线:

Dispatcher.Invoke(new Action(() => 
我有

A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll  
Additional information: Thread was being aborted.
我的视图包含以下代码:

建造师

public MyView(ConcurrentQueue<MyItem> actionReports, ManualResetEvent actionCompletedEvent, string actionName)
{
    _actionReports = actionReports;
    _actionCompletedEvent = actionCompletedEvent;
    _actionName = actionName;

    InitializeComponent();
    DataContext = this;

    this.Loaded += MyView_Loaded;
}

void MyView_Loaded(object sender, RoutedEventArgs e)
{
    var worker = new BackgroundWorker();
    worker.DoWork += (o, ea) =>
    {
        while (true)
        {
            if (_actionCompletedEvent.WaitOne(0))
            {
         // Issue
                Dispatcher.Invoke(new Action(() =>
                {
                    Close();
                }));

                Thread.Sleep(100);
            }

            while (!_actionReports.IsEmpty)
            {
                // Do some stuff
            }
        }
    };

    worker.RunWorkerAsync();
}

后台线程在应用程序退出时由运行时自动中止。通常,它们不会抛出
threadAbortException
(请参阅)

调用调度程序会导致在调度线程上运行方法,但由于您使用的是
Invoke()
而不是
BeginInvoke()
,因此调度程序需要通知后台线程该方法已完成。我怀疑这就是提出例外的地方,但这只是我的猜测

尝试按如下方式捕获异常:

try
{
    Dispatcher.Invoke(new Action(() =>
    {
         Close();
    }));
}
catch (ThreadAbortException)
{
    Thread.ResetAbort(); 
}
尽管如果在调度线程上引发异常,这可能没有帮助。如果这不起作用,请尝试
BeginInvoke()


顺便说一句,如果你在启动调用的lambda时延迟一段时间并在那一点关闭应用程序,你可能会更容易复制这个bug。这意味着后台线程将在lambda完成时中止。

我通常至少会尝试取消
窗口中的
BackgroundWorker
异步操作。一旦关闭
事件,并捕获挂起的取消。您仍然需要注意ThreadAbortException,但前提是您的异步进程是长期运行的

private BackgroundWorker _worker;

private void MyView_Loaded(object sender, RoutedEventArgs e)
{
    _worker = new BackgroundWorker();
    _worker.WorkerSupportsCancellation = true;
    _worker.DoWork += (o, ea) =>
    {
        while (true)
        {
            if (_actionCompletedEvent.WaitOne(0))
            {
                if (_worker.CancellationPending)
                {
                    ea.Cancel = true;
                    return;
                }

                // Issue
                Dispatcher.Invoke(new Action(() =>
                {
                    Close();
                }));

                Thread.Sleep(100);
            }

            while (!_actionReports.IsEmpty)
            {
                // Do some stuff
            }
        }
    };
}

protected override void OnClosing(CancelEventArgs e)
{
    _worker.CancelAsync();
}

添加上述代码后,我现在在Dispatcher.Run()上的WindowLauncher中遇到了问题;有类似的信息“附加信息:线程正在中止”。有什么想法吗?
private BackgroundWorker _worker;

private void MyView_Loaded(object sender, RoutedEventArgs e)
{
    _worker = new BackgroundWorker();
    _worker.WorkerSupportsCancellation = true;
    _worker.DoWork += (o, ea) =>
    {
        while (true)
        {
            if (_actionCompletedEvent.WaitOne(0))
            {
                if (_worker.CancellationPending)
                {
                    ea.Cancel = true;
                    return;
                }

                // Issue
                Dispatcher.Invoke(new Action(() =>
                {
                    Close();
                }));

                Thread.Sleep(100);
            }

            while (!_actionReports.IsEmpty)
            {
                // Do some stuff
            }
        }
    };
}

protected override void OnClosing(CancelEventArgs e)
{
    _worker.CancelAsync();
}