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); }