WebView2中如何直接访问C#宿主对象返回数组的属性
解决WebView2中C#宿主对象返回数组属性需异步访问的问题
你遇到的问题是WebView2默认的宿主对象代理机制导致的——C#对象的每个属性在JS中都会以Promise形式返回,因为跨进程通信是异步的。下面提供两种无需使用sync宿主对象的解决方案:
方案一:C#端返回JSON字符串(推荐)
直接在C#层将实体数组序列化为JSON字符串,JS端解析后得到普通JavaScript对象,属性可直接访问,同时减少跨进程通信次数,提升性能。
修改后的C#代码
using System.Text.Json; public string GetEntitiesAsJson() { // 模拟耗时操作 Thread.Sleep(1000); var entities = new[] { new MyEntity { Name = "foo" }, new MyEntity { Name = "bar" }, new MyEntity { Name = "baz" } }; return JsonSerializer.Serialize(entities); }
对应的JavaScript代码
const jsonStr = await window.chrome.webview.hostObjects.myType.GetEntitiesAsJson(); const ents = JSON.parse(jsonStr); for (const p of ents) { console.log(p.name); // 直接访问属性,无需await }
方案二:JS端封装工具函数批量解析代理对象
如果无法修改C#端代码,可以在JS中封装函数,将宿主对象代理数组转换为普通JS对象数组,提前异步解析所有需要的属性。
JavaScript工具函数及使用示例
// 批量解析宿主对象代理数组,转换为普通JS对象 async function unwrapHostEntities(hostEntities) { return Promise.all(hostEntities.map(async entity => { const plainObj = {}; // 列出需要解析的属性(根据MyEntity的实际属性调整) const targetProps = ['name']; for (const prop of targetProps) { plainObj[prop] = await entity[prop]; } return plainObj; })); } // 使用方式 const proxyEnts = await window.chrome.webview.hostObjects.myType.GetEntities(); const ents = await unwrapHostEntities(proxyEnts); for (const p of ents) { console.log(p.name); // 直接访问属性 }
原理说明
WebView2的hostObjects默认采用异步代理模式,每个属性访问都会触发一次跨进程的异步调用,因此返回Promise。上述两种方案要么一次性传递所有数据,要么批量完成异步解析,之后就能像操作普通JS对象一样直接访问属性,同时避免了sync版本阻塞UI线程的问题。
内容的提问来源于stack exchange,提问作者blins
相关产品推荐
相关产品推荐

