我有一种Async
方法可以关闭一些浏览器弹出窗口。
有时,应用程序在退出时崩溃并出现.NET Runtime
错误(mscorwks.dll异常代码为0xc0000005)。我怀疑它Thread
是在被迫终止时发生的,因为我看不到记录的“线程退出”行。会不会是里面的代码ExtendedIeBrowser
抛出一个unhandled exception
?
您可以在下面找到源代码。
internal void KeepAliveAsync()
{
PageController controller = new PageController();
controller.Initialize(siteWebBrowser);
var thread = new Thread(() =>
{
_logger.Debug("Thread start - KeepAliveAsync");
try
{
while (!Program.ShouldAbortBackgroundOperations())
{
try
{
if (controller.TryCloseTimeoutWarningPopup())
{
_logger.Info("KeepAliveAsync: Closed popup successfully");
}
Thread.Sleep(5000);
}
catch (Exception ex)
{
_logger.ErrorException("KeepAliveAsync", ex);
}
}
}
catch (Exception ex)
{
_logger.ErrorException("KeepAliveAsync", ex);
}
_logger.Debug("Thread exit - KeepAliveAsync");
});
thread.Name = "KeepAliveAsync";
thread.IsBackground = true;
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
使用PageController
这个类:
public class ExtendedIeBrowser : IE
{
private IntPtr hwnd;
private static Logger _logger = LogManager.GetCurrentClassLogger();
public ExtendedIeBrowser(WebBrowser webBrowserControl) : base(webBrowserControl.ActiveXInstance, false)
{
}
public void Initialize(WebBrowser webBrowserControl)
{
hwnd = webBrowserControl.FindForm().Handle;
// Start the dialog watcher or else the browser won't be able to attach the handler.
StartDialogWatcher();
}
public override IntPtr hWnd
{
get
{
return hwnd;
}
}
protected override void Dispose(bool disposing)
{
hwnd = IntPtr.Zero;
base.Dispose(disposing);
}
}
这是:
internal static bool ShouldAbortBackgroundOperations()
{
bool should = true;
try
{
should &= Application.OpenForms.Cast<Form>().Count(f => f.ShowInTaskbar) == 0; // at least one form is shown in the taskbar
}
catch (Exception ex)
{
_logger.ErrorException("ShouldAbortBackgroundOperations", ex);
should = false;
}
return should;
}
关闭弹出窗口的方法(字面意思是网页内的 div):
internal bool TryCloseTimeoutWarningPopup()
{
bool success = false;
try
{
Div glassPane = Browser.Div(Find.ByClass(PageConstants.ModalGlassPaneClass));
if (glassPane.Exists) // there is a popup
{
Div parent = (Div)glassPane.Parent;
if (parent.InnerHtml.Contains(PageConstants.WarningLoggingOutPrimaryKeyword)) // correct content on popup
{
WatiN.Core.Button button = parent.Divs[0].Buttons[0];
ClickOnElement(button);
success = true;
}
}
}
catch (Exception ex)
{
_logger.ErrorException("CloseTimeoutWarningPopup", ex);
throw;
}
return success;
}
如果程序在 Abort 检查和 CloseTimeoutWarningPopup() 执行后关闭怎么办?我注意到在我关闭应用程序后的某个时间点,该if (glassPane)
行正在等待元素出现并尝试访问已处置的对象。是否该对象的内存地址不再可用并因此被拒绝?