C#使用CefSharp上传文件后异步获取HTML源码并返回的问题
问题解决
你遇到的是典型的异步执行顺序问题:LoadingStateChanged事件回调、GetSourceAsync都属于异步逻辑,不会阻塞当前SendFileWebBrowser方法的执行流,所以方法会在拿到响应源码前就提前返回空值。你可以通过TaskCompletionSource封装异步逻辑,把方法改成异步等待模式来解决。
完整修改代码
// 按钮点击事件改成异步,事件处理器用async void是合规的 private async void button6_Click(object sender, EventArgs e) { // ... 从目录读取图片的代码 ... for (int k = 0; k < itemImages.Length; k++) { string responseFromSendFile = await SendFileWebBrowser(itemImages[k]); JObject jObject = JObject.Parse(responseFromSendFile); string imageUrl = (string)jObject.SelectToken("imageUrl"); } } // 方法返回类型改成Task<string>,支持异步等待 public Task<string> SendFileWebBrowser(string filePath) { var tcs = new TaskCompletionSource<string>(); string htmlReturnImageUploadResponse = string.Empty; // .... 填充其他请求参数的代码 .... request.PostData.AddData(bytes); frame.LoadRequest(request); // 先声明回调委托,方便后续解绑 EventHandler<LoadingStateChangedEventArgs> loadingHandler = null; loadingHandler = (sender1, args) => { if (!args.IsLoading) { // 加载完成后先解绑事件,避免重复触发 chromiumWebBrowser1.LoadingStateChanged -= loadingHandler; chromiumWebBrowser1.GetSourceAsync().ContinueWith(taskHtml => { htmlReturnImageUploadResponse = taskHtml.Result; // 访问UI控件需要切回UI线程,避免跨线程异常 richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(htmlReturnImageUploadResponse + "11111111"); })); // 设置异步任务完成,返回结果 tcs.SetResult(htmlReturnImageUploadResponse); }); } }; chromiumWebBrowser1.LoadingStateChanged += loadingHandler; return tcs.Task; }
注意事项
- 循环内加了
await关键字,会等待当前图片上传、拿到响应后再处理下一张图片,符合你的原有逻辑 - 每次注册
LoadingStateChanged事件后,触发完成立刻解绑,避免多次调用方法导致重复注册回调、逻辑混乱 - 所有UI控件的操作都通过
Invoke切换到UI线程执行,不会触发跨线程访问异常
内容的提问来源于stack exchange,提问作者SergejoWizz
相关产品推荐
相关产品推荐

