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