public void Dispose() { if (!m_Disposed) { if (m_ExecutionThread != null) { if (m_ExecutionThread.ThreadState != ThreadState.Unstarted) { if (m_ExecutionThread.ThreadState != ThreadState.Stopped) { //Note: This abort is done because joining on the thread alone will not work since the thread marshalls to the UI thread for WebBrowser stuff - // if the UI thread blocks on the join, the marshalling will get stuck and cause a deadlock. // Therefore, if the class instance is being disposed and the thread is not done, to hell with the thread. // Normally, nothing should ever call Dispose WHILE a sequence is running except for application termination in which case the abort is acceptable. m_ExecutionThread.Abort(); } m_ExecutionThread.Join(); } m_ExecutionThread = null; } if (m_StepExecutorProvider != null) { m_StepExecutorProvider.Dispose(); m_StepExecutorProvider = null; } m_Context.DataContext.Clear(); m_Context.ExecutionStack.Dispose(); m_Sequence = null; m_Disposed = true; } }
public AutomationEngine(WebBrowser browser) { m_StepExecutorProvider = new StepExecutorProvider(); m_Context = new ExecutionContext(new WebBrowserHelper(browser)); }