gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 13:07:38 26 4
gpt4 key购买 nike

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

在线:

Dispatcher.Invoke(new Action(() => 

我有

A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll  
Additional information: Thread was being aborted.

我的 View 有以下代码:

构造函数

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();
}

窗口初始化

public WindowLauncher(ManualResetEvent actionCompletedEvent, ManualResetEvent reportWindowClosedEvent, string actionName)
{
_actionCompletedEvent = actionCompletedEvent;
_reportWindowClosedEvent = reportWindowClosedEvent;
_actionName = actionName;

Thread thread = new Thread(new ThreadStart(() =>
{
_reportWindow = new MyView(_messageQueue, _actionCompletedEvent, actionName);
_reportWindow.Show();

// InvokeShutdown to terminate the thread properly
_reportWindow.Closed += (sender, args) =>
{
_reportWindow.Dispatcher.InvokeShutdown();
};
_resetEvent.Set();
Dispatcher.Run();
}));

thread.Name = "MyWindowThread";
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
}

最佳答案

我通常至少会尝试取消 Window.OnClosing 事件中的 BackgroundWorker 异步操作并捕获挂起的取消。您仍然需要注意 ThreadAbortExceptions,但前提是您的异步​​进程长时间运行。

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();
}

关于c# - 线程传递数据和窗口关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30211442/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com