2

Asyncブラウザのポップアップを閉じるメソッドがあります。

.NET Runtime終了時にエラー (例外コード0xc0000005のmscorwks.dll )でアプリケーションがクラッシュする場合があります。ログに記録された「スレッド終了」行が表示されないため、が強制終了されたときに発生すると思われます。をスローするのは 内のコードでしょうか?ThreadExtendedIeBrowserunhandled 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;
    }

ポップアップを閉じるメソッド (文字通り、Web ページ内の 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)行が要素が表示されるのを待っていて、破棄されたオブジェクトにアクセスしようとしたことに気付きました。そのオブジェクトのメモリ アドレスが使用できなくなったため、拒否された可能性はありますか?

4

1 に答える 1

1

問題は、 がアクセスしようとしていた一部のコントロールがcontroller、スレッドの終了前に破棄され、アクセス違反の例外が発生したことでした。

于 2012-12-22T12:58:06.600 に答える