这是 this question 的后续内容.
我正在将 WPF 应用程序从 CEFSharp 移植到 WebView2。我有一个 HostObject,需要从 WebView2 窗口中的 js 访问。就是这样,精简了。
using System;
using System.Runtime.InteropServices;
namespace webview2Demo
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Api
{
public string Username { get; set; }
public string Version = "1.1.1";
public Api() //ctor
{
}
}
}
我可以在 WebView2 控件的 NavigationStarting 事件中成功使用此行,使对象在 Javascript 中可见。到目前为止一切顺利。
webView.CoreWebView2.AddHostObjectToScript("api", new API());
我可以像这样检索公共(public)属性和成员。到目前为止一切顺利。
(async function foo () {
const api = chrome.webview.hostObjects.api
const ver = await api.Version
alert (ver)
})();
我的问题:我可以在没有任何异步竞争条件或死锁风险的情况下可靠地设置这样的属性吗? api.Username = 'whoever'
它似乎有效,但我还没有找到它的记录。
(async function foo () {
const api = chrome.webview.hostObjects.api
api.Username = 'whoever'
const user = await api.Username
alert (user)
})();
文档说 HostObject 是通过 Promises 公开的。 我是否正确击球二传手?
最佳答案
当您在 JavaScript 代理上为通过 CoreWebView2.AddHostObjectToScript 创建的主机对象设置属性时,与获取属性或调用方法不同,分配返回与分配的值相同的值,而不是表示分配完成的 promise 。属性分配确实会生成一条消息发送回 WebView2 主机应用程序进程,并且属性将被分配,只是您不会 promise 在完成时告诉您。
设置主机属性
或者,您可以使用setHostProperty ,一个将执行属性分配并返回一个 promise 的方法,该 promise 将在属性分配完成时解析。
(async function foo () {
const api = chrome.webview.hostObjects.api
await api.setHostProperty('Username', 'whoever');
const user = await api.Username
alert (user)
})();
同步代理
还有代理的同步版本。只要异步代理返回 Promise,同步代理就会阻塞 JavaScript 线程,等待 WebView2 主机进程的响应。通常,您不想阻止 JavaScript 线程等待跨进程调用,但在某些情况下,这可能更实用或更可接受。异步代理有一个 sync
方法,它将返回代理的同步版本(异步)。
(async function foo () {
// Note the one await call to get from async proxies to sync proxies
const syncHostObjects = await chrome.webview.hostObjects.sync;
const api = syncHostObjects.api;
api.Username = 'whoever';
const user = api.Username
alert (user)
})();
依赖队列
由于所有 JavaScript 代理消息都在同一队列上传输,并且必须在 WebView2 主机应用程序进程中的同一线程上处理,因此使用属性 setter 而不是等待其完成然后调用 getter 可能会仍然强制获取消息等待设置完成并且您的原始代码没有问题。
关于javascript - WebView2:通过 Javascript 代码在 C# 中设置对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68623267/