示例#1
0
        private void Dispose(bool isDisposing = true)
        {
            if (isDisposing)
            {
                lock (SyncRoot) {
                    if (this.isDisposing)
                    {
                        return;
                    }

                    this.isDisposing = true;
                }
                GC.SuppressFinalize(this);
            }

            var disposed = false;

            void InternalDispose()
            {
                if (disposed)
                {
                    return; // bail-out
                }

                disposed = true;

                AsyncCancellationTokenSource?.Cancel();

                WebViewInitialized        = null;
                BeforeNavigate            = null;
                BeforeResourceLoad        = null;
                Navigated                 = null;
                LoadFailed                = null;
                DownloadProgressChanged   = null;
                DownloadCompleted         = null;
                DownloadCancelled         = null;
                JavascriptContextCreated  = null;
                TitleChanged              = null;
                UnhandledAsyncException   = null;
                JavascriptContextReleased = null;

                foreach (var disposable in disposables.Concat(JsExecutors?.Values))
                {
                    disposable?.Dispose();
                }

                Disposed?.Invoke();
            }

            if (JavascriptPendingCalls?.CurrentCount > 1)
            {
                // avoid dead-lock, wait for all pending calls to finish
                Task.Run(() => {
                    JavascriptPendingCalls?.Signal(); // remove dummy entry
                    JavascriptPendingCalls?.Wait();
                    InternalDispose();
                });
                return;
            }

            InternalDispose();
        }
示例#2
0
文件: WebView.cs 项目: wuzlai/WebView
        public void Dispose()
        {
            lock (SyncRoot) {
                if (isDisposing)
                {
                    return;
                }

                isDisposing = true;
            }

            GC.SuppressFinalize(this);

            var disposed = false;

            void InternalDispose()
            {
                if (disposed)
                {
                    return; // bail-out
                }

                disposed = true;

                AsyncCancellationTokenSource.Cancel();

                WebViewInitialized        = null;
                BeforeNavigate            = null;
                BeforeResourceLoad        = null;
                Navigated                 = null;
                LoadFailed                = null;
                DownloadProgressChanged   = null;
                DownloadCompleted         = null;
                DownloadCancelled         = null;
                JavascriptContextCreated  = null;
                TitleChanged              = null;
                UnhandledAsyncException   = null;
                RenderProcessCrashed      = null;
                JavascriptContextReleased = null;

                try {
                    foreach (var jsExecutor in JsExecutors.Values)
                    {
                        jsExecutor.Dispose();
                    }
                } catch (Exception e) {
                    throw new Exception("Exception ocurred while disposing " + nameof(JsExecutors), e);
                }

                if (disposables != null)
                {
                    foreach (var disposable in disposables)
                    {
                        disposable.Dispose();
                    }
                }

                Disposed?.Invoke();
            }

            // avoid dead-lock, wait for all pending calls to finish
            JavascriptCallFinished += () => {
                if (javascriptPendingCalls == 0)
                {
                    Dispatcher.BeginInvoke((Action)InternalDispose);
                }
            };

            if (javascriptPendingCalls > 0)
            {
                // JavascriptCallFinished event will trigger InternalDispose,
                // this check must come after registering event to avoid losing the event call
                return;
            }

            InternalDispose();
        }
示例#3
0
        private void InnerDispose()
        {
            lock (SyncRoot) {
                if (isDisposing)
                {
                    return;
                }
                isDisposing = true;
            }

            var disposed = false;

            void InternalDispose()
            {
                if (disposed)
                {
                    return; // bail-out
                }

                disposed = true;

                AsyncCancellationTokenSource?.Cancel();

                chromium.JavascriptContextCreated  -= OnJavascriptContextCreated;
                chromium.JavascriptContextReleased -= OnJavascriptContextReleased;

                WebViewInitialized        = null;
                BeforeNavigate            = null;
                BeforeResourceLoad        = null;
                Navigated                 = null;
                LoadFailed                = null;
                DownloadProgressChanged   = null;
                DownloadCompleted         = null;
                DownloadCancelled         = null;
                JavascriptContextCreated  = null;
                TitleChanged              = null;
                UnhandledAsyncException   = null;
                JavascriptContextReleased = null;

                // dispose the js executors before the browser to prevent (the browser) from throwing cancellation exceptions
                DisposeJavascriptExecutors();

                foreach (var disposable in disposables)
                {
                    disposable?.Dispose();
                }

                Disposed?.Invoke();
            }

            if (JavascriptPendingCalls?.CurrentCount > 1)
            {
                // avoid dead-lock, wait for all pending calls to finish
                Task.Run(() => {
                    JavascriptPendingCalls?.Signal(); // remove dummy entry
                    JavascriptPendingCalls?.Wait();
                    InternalDispose();
                });
                return;
            }

            InternalDispose();
        }