Exemplo n.º 1
0
        private static async Task <byte[]> ExecuteDevToolsMethodInternalAsync(IChromiumWebView webview, string method, CefDictionaryValue parameters, CancellationToken cancellationToken)
        {
            CefBrowser browser = webview.BrowserObject;

            if (browser is null)
            {
                throw new InvalidOperationException();
            }

            cancellationToken.ThrowIfCancellationRequested();

            CefBrowserHost         browserHost    = browser.Host;
            DevToolsProtocolClient protocolClient = GetProtocolClient(browserHost);

            await CefNetSynchronizationContextAwaiter.GetForThread(CefThreadId.UI);

            cancellationToken.ThrowIfCancellationRequested();

            int messageId = browserHost.ExecuteDevToolsMethod(protocolClient.IncrementMessageId(), method, parameters);

            protocolClient.UpdateLastMessageId(messageId);
            DevToolsMethodResult r;

            if (cancellationToken.CanBeCanceled)
            {
                Task <DevToolsMethodResult> waitTask = protocolClient.WaitForMessageAsync(messageId);
                await Task.WhenAny(waitTask, Task.Delay(Timeout.Infinite, cancellationToken)).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
                r = waitTask.Result;
            }
            else
            {
                r = await protocolClient.WaitForMessageAsync(messageId).ConfigureAwait(false);
            }
            if (r.Success)
            {
                return(r.Result);
            }

            CefValue errorValue = CefApi.CefParseJSONBuffer(r.Result, CefJsonParserOptions.AllowTrailingCommas);

            if (errorValue is null)
            {
                throw new DevToolsProtocolException($"An unknown error occurred while trying to execute the '{method}' method.");
            }
            throw new DevToolsProtocolException(errorValue.GetDictionary().GetString("message"));
        }
        /// <summary>
        /// Returns the <see cref="CefNetSynchronizationContextAwaiter"/> for the specified CEF thread.
        /// </summary>
        /// <param name="threadId">The CEF thread identifier.</param>
        /// <returns>The <see cref="CefNetSynchronizationContextAwaiter"/> for the CEF thread.</returns>
        public static CefNetSynchronizationContextAwaiter GetForThread(CefThreadId threadId)
        {
            CefNetSynchronizationContextAwaiter instance;

            _SyncRoot.EnterReadLock();
            try
            {
                _Awaiters.TryGetValue(threadId, out instance);
            }
            finally
            {
                _SyncRoot.ExitReadLock();
            }
            if (instance != null)
            {
                return(instance);
            }

            // These awaiters should have been added in the static constructor.
            if (threadId == CefThreadId.Renderer || threadId == CefThreadId.UI)
            {
                throw new ArgumentOutOfRangeException(nameof(threadId));
            }

            _SyncRoot.EnterWriteLock();
            try
            {
                if (!_Awaiters.TryGetValue(threadId, out instance))
                {
                    instance = new CefNetSynchronizationContextAwaiter(threadId);
                    _Awaiters.Add(threadId, instance);
                }
            }
            finally
            {
                _SyncRoot.ExitWriteLock();
            }
            return(instance);
        }