同步创建浏览器
概述
同步创建浏览器是FBro提供的一种在UI线程中直接创建浏览器实例的方法。与异步创建不同,同步创建会立即返回浏览器对象,但必须在CEF的UI线程中执行。
核心概念
线程要求
- 必须在UI线程执行:同步创建浏览器的操作必须在CEF的UI线程中进行
- 任务投递机制:使用
FBroSharpTaskRunner.CefPostTask将创建任务投递到UI线程 - 立即返回:创建成功后立即返回浏览器实例,无需等待回调
适用场景
- 需要立即获取浏览器实例的场景
- 在已知UI线程环境下的浏览器创建
- 批量创建浏览器时的同步控制
浏览器事件回调类详解
BrowserEvent基础结构
同步创建浏览器同样需要使用BrowserEvent事件回调类。以下是一个专门为同步创建优化的事件处理器:
csharp
using FBroSharp;
using FBroSharp.Const;
using FBroSharp.DataType;
using FBroSharp.Event;
using FBroSharp.Lib;
using FBroSharp.Value;
using System;
using System.Collections.Generic;
using System.Reflection;
using FBroSharp.Callback;
using System.IO;
namespace SyncBrowserExample
{
/// <summary>
/// 同步创建浏览器的事件处理器
/// 针对同步创建场景优化的事件回调类
/// </summary>
public class SyncBrowserEvent : FBroSharpBrowserEvent
{
private readonly Action<IFBroSharpBrowser> onCreated;
private readonly Action<IFBroSharpBrowser> onClosed;
private readonly string browserPurpose;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="onCreated">浏览器创建完成回调</param>
/// <param name="onClosed">浏览器关闭回调</param>
/// <param name="purpose">浏览器用途描述</param>
public SyncBrowserEvent(Action<IFBroSharpBrowser> onCreated = null, Action<IFBroSharpBrowser> onClosed = null, string purpose = "")
{
this.onCreated = onCreated;
this.onClosed = onClosed;
this.browserPurpose = purpose;
}
#region 核心生命周期事件
/// <summary>
/// 浏览器创建完成事件
/// 同步创建场景下,此事件在浏览器可用时立即触发
/// </summary>
public override void OnAfterCreated(IFBroSharpBrowser browser, IFBroSharpDictionaryValue extrainfo)
{
Console.WriteLine($"[同步浏览器创建] ID: {browser.GetIdentifier()}, 用途: {browserPurpose}");
try
{
// 立即配置浏览器
ConfigureSyncBrowser(browser);
// 执行自定义创建完成回调
onCreated?.Invoke(browser);
Console.WriteLine($"同步浏览器配置完成: {browser.GetIdentifier()}");
}
catch (Exception ex)
{
Console.WriteLine($"同步浏览器配置失败: {ex.Message}");
}
}
/// <summary>
/// 浏览器关闭前事件
/// </summary>
public override void OnBeforeClose(IFBroSharpBrowser browser)
{
Console.WriteLine($"[同步浏览器关闭] ID: {browser.GetIdentifier()}");
try
{
// 执行自定义关闭回调
onClosed?.Invoke(browser);
// 清理同步创建的资源
CleanupSyncResources(browser);
}
catch (Exception ex)
{
Console.WriteLine($"同步浏览器清理失败: {ex.Message}");
}
}
/// <summary>
/// 控制浏览器关闭行为
/// </summary>
public override bool DoClose(IFBroSharpBrowser browser)
{
Console.WriteLine($"[同步浏览器] 请求关闭: {browser.GetIdentifier()}");
return false; // 允许关闭
}
#endregion
#region 页面加载事件
/// <summary>
/// 加载状态变化 - 针对同步场景优化
/// </summary>
public override void OnLoadingStateChange(IFBroSharpBrowser browser, bool isLoading, bool canGoBack, bool canGoForward)
{
string status = isLoading ? "加载中" : "加载完成";
Console.WriteLine($"[同步浏览器-{browser.GetIdentifier()}] {status}");
if (!isLoading)
{
// 页面加载完成,可以立即执行后续操作
OnSyncPageLoadCompleted(browser);
}
}
/// <summary>
/// 页面加载完成处理
/// </summary>
private void OnSyncPageLoadCompleted(IFBroSharpBrowser browser)
{
try
{
// 注入一些有用的JavaScript工具
string utilityJS = @"
// 添加同步浏览器标识
window.FBroSyncBrowser = true;
window.FBroBrowserId = " + browser.GetIdentifier() + @";
// 页面加载完成标记
console.log('FBro同步浏览器页面加载完成, ID: ' + window.FBroBrowserId);
// 添加实用工具函数
window.FBroUtils = {
getBrowserId: function() { return window.FBroBrowserId; },
getPageInfo: function() {
return {
url: window.location.href,
title: document.title,
browserId: window.FBroBrowserId
};
}
};
";
browser.GetMainFrame().ExecuteJavaScript(utilityJS, "", 0);
}
catch (Exception ex)
{
Console.WriteLine($"同步浏览器页面初始化失败: {ex.Message}");
}
}
#endregion
#region 右键菜单增强
/// <summary>
/// 自定义右键菜单 - 同步浏览器版本
/// </summary>
public override void OnBeforeContextMenu(IFBroSharpBrowser browser, IFBroSharpFrame frame, IFBroSharpContextMenuParams menu_params, IFBroSharpMenuModel model)
{
// 添加同步浏览器专用菜单
model.AddSeparator();
var syncMenu = model.AddSubMenu(20000, "同步浏览器工具");
syncMenu.AddItem(20001, $"浏览器ID: {browser.GetIdentifier()}");
syncMenu.AddSeparator();
syncMenu.AddItem(20002, "获取页面信息");
syncMenu.AddItem(20003, "执行测试脚本");
syncMenu.AddItem(20004, "开发者工具");
}
/// <summary>
/// 处理自定义菜单命令
/// </summary>
public override bool OnContextMenuCommand(IFBroSharpBrowser browser, IFBroSharpFrame frame, IFBroSharpContextMenuParams menu_params, int command_id, FBroSharpEventFlags event_flags)
{
switch (command_id)
{
case 20002: // 获取页面信息
GetSyncBrowserPageInfo(browser, frame);
return true;
case 20003: // 执行测试脚本
ExecuteSyncTestScript(browser, frame);
return true;
case 20004: // 开发者工具
browser.ShowDevTools("同步浏览器开发工具", IntPtr.Zero, 0, 0, 1200, 800, default, default, default, default);
return true;
}
return false;
}
#endregion
#region 辅助方法
/// <summary>
/// 配置同步创建的浏览器
/// </summary>
private void ConfigureSyncBrowser(IFBroSharpBrowser browser)
{
// 设置合适的缩放级别
browser.SetZoomLevel(0.0);
// 可以在这里添加其他同步浏览器的特殊配置
Console.WriteLine($"同步浏览器基础配置完成: {browser.GetIdentifier()}");
}
/// <summary>
/// 获取同步浏览器页面信息
/// </summary>
private void GetSyncBrowserPageInfo(IFBroSharpBrowser browser, IFBroSharpFrame frame)
{
try
{
string jsCode = @"
var info = window.FBroUtils ? window.FBroUtils.getPageInfo() : {
url: window.location.href,
title: document.title,
browserId: 'unknown'
};
alert('同步浏览器信息:\n' +
'ID: ' + info.browserId + '\n' +
'URL: ' + info.url + '\n' +
'Title: ' + info.title + '\n' +
'Domain: ' + window.location.hostname);
";
frame.ExecuteJavaScript(jsCode, "", 0);
}
catch (Exception ex)
{
Console.WriteLine($"获取页面信息失败: {ex.Message}");
}
}
/// <summary>
/// 执行同步测试脚本
/// </summary>
private void ExecuteSyncTestScript(IFBroSharpBrowser browser, IFBroSharpFrame frame)
{
try
{
string testJS = @"
console.log('同步浏览器测试脚本开始执行...');
// 测试DOM操作
var testDiv = document.createElement('div');
testDiv.id = 'fbro-sync-test';
testDiv.style.cssText = 'position:fixed;top:10px;right:10px;background:#4CAF50;color:white;padding:10px;border-radius:5px;z-index:9999;font-family:Arial;';
testDiv.innerHTML = '同步浏览器测试 ✓<br>ID: ' + (window.FBroBrowserId || 'unknown');
document.body.appendChild(testDiv);
// 3秒后移除测试元素
setTimeout(function() {
var testEl = document.getElementById('fbro-sync-test');
if (testEl) testEl.remove();
}, 3000);
console.log('同步浏览器测试脚本执行完成');
";
frame.ExecuteJavaScript(testJS, "", 0);
}
catch (Exception ex)
{
Console.WriteLine($"执行测试脚本失败: {ex.Message}");
}
}
/// <summary>
/// 清理同步浏览器资源
/// </summary>
private void CleanupSyncResources(IFBroSharpBrowser browser)
{
try
{
Console.WriteLine($"清理同步浏览器资源: {browser.GetIdentifier()}");
// 在这里可以添加特定于同步浏览器的清理逻辑
// 例如:保存状态、清理临时文件等
}
catch (Exception ex)
{
Console.WriteLine($"清理同步浏览器资源失败: {ex.Message}");
}
}
#endregion
}
}基础用法
简单同步创建
csharp
private void CreateSyncBrowser_Click(object sender, EventArgs e)
{
// 配置窗口信息
FBroSharpWindowsInfo windows_info = new FBroSharpWindowsInfo
{
parent_window = this.Handle,
x = 0,
y = 0,
width = this.ClientSize.Width,
height = this.ClientSize.Height
};
// 创建浏览器事件回调类
var browser_event = new SyncBrowserEvent(
onCreated: browser => {
Console.WriteLine($"同步浏览器创建完成: {browser.GetIdentifier()}");
},
onClosed: browser => {
Console.WriteLine($"同步浏览器已关闭: {browser.GetIdentifier()}");
},
purpose: "基础同步浏览器"
);
// 创建同步创建任务
FBroSharpTask createBrowserTask = new CreateBrowserTask(
"https://www.baidu.com",
windows_info,
default,
default,
default,
browser_event,
default
);
// 投递任务到UI线程
bool postTaskResult = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, createBrowserTask);
if (postTaskResult)
{
Console.WriteLine("浏览器创建任务成功投递到UI线程");
}
else
{
Console.WriteLine("浏览器创建任务投递失败");
}
}自定义任务类
csharp
/// <summary>
/// 同步创建浏览器的自定义任务类
/// </summary>
public class CreateBrowserTask : FBroSharpTask
{
private readonly string url;
private readonly FBroSharpWindowsInfo windowsInfo;
private readonly FBroSharpBrowserSetting browserSetting;
private readonly FBroSharpRequestContext requestContext;
private readonly FBroSharpDictionaryValue extraInfo;
private readonly FBroSharpBrowserEvent browserEvent;
private readonly FBroSharpEventDisableControl eventDisableControl;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="url">初始加载的URL</param>
/// <param name="windowsInfo">窗口信息配置</param>
/// <param name="browserSetting">浏览器设置</param>
/// <param name="requestContext">请求上下文</param>
/// <param name="extraInfo">额外参数</param>
/// <param name="browserEvent">浏览器事件回调</param>
/// <param name="eventDisableControl">事件禁用控制</param>
public CreateBrowserTask(
string url,
FBroSharpWindowsInfo windowsInfo,
FBroSharpBrowserSetting browserSetting,
FBroSharpRequestContext requestContext,
FBroSharpDictionaryValue extraInfo,
FBroSharpBrowserEvent browserEvent,
FBroSharpEventDisableControl eventDisableControl)
{
this.url = url;
this.windowsInfo = windowsInfo;
this.browserSetting = browserSetting;
this.requestContext = requestContext;
this.extraInfo = extraInfo;
this.browserEvent = browserEvent;
this.eventDisableControl = eventDisableControl;
}
/// <summary>
/// 执行同步创建浏览器的任务
/// </summary>
public override void Execute()
{
try
{
Console.WriteLine($"开始同步创建浏览器: {url}");
// 调用同步创建方法并获取浏览器对象
FBroSharpBrowser browser = FBroSharpControl.CreateSync(
url,
windowsInfo,
browserSetting,
requestContext,
extraInfo,
browserEvent,
eventDisableControl
);
if (browser != null && browser.IsValid())
{
// 立即加载初始URL
browser.GetMainFrame().LoadURL(url);
// 可以在这里进行进一步的浏览器配置
ConfigureBrowser(browser);
Console.WriteLine($"同步创建浏览器成功,ID: {browser.GetIdentifier()}");
}
else
{
Console.WriteLine("同步创建浏览器失败,返回无效的浏览器实例");
}
}
catch (Exception ex)
{
Console.WriteLine($"同步创建浏览器失败: {ex.Message}");
Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
}
}
/// <summary>
/// 配置浏览器的其他属性
/// </summary>
/// <param name="browser">浏览器实例</param>
private void ConfigureBrowser(FBroSharpBrowser browser)
{
try
{
// 设置缩放级别
browser.SetZoomLevel(0.0);
// 可以添加其他配置
// browser.SetProxy("http://proxy.com:8080");
Console.WriteLine($"浏览器配置完成: {browser.GetIdentifier()}");
}
catch (Exception ex)
{
Console.WriteLine($"配置浏览器失败: {ex.Message}");
}
}
}高级用法
批量同步创建浏览器
csharp
public class BatchSyncBrowserCreator
{
private readonly List<FBroSharpBrowser> browsers = new List<FBroSharpBrowser>();
private int completedCount = 0;
private readonly int totalCount;
private readonly object lockObject = new object();
public BatchSyncBrowserCreator(int count)
{
totalCount = count;
}
/// <summary>
/// 批量创建多个同步浏览器
/// </summary>
public void CreateMultipleBrowsers()
{
string[] urls = {
"https://www.baidu.com",
"https://www.bing.com",
"https://www.google.com",
"https://www.yahoo.com"
};
for (int i = 0; i < totalCount; i++)
{
string url = urls[i % urls.Length];
var task = new BatchCreateBrowserTask(url, i, this);
bool result = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
if (!result)
{
Console.WriteLine($"浏览器 {i} 任务投递失败");
}
// 添加小延迟避免同时创建过多浏览器
System.Threading.Thread.Sleep(200);
}
}
/// <summary>
/// 浏览器创建完成回调
/// </summary>
public void OnBrowserCreated(FBroSharpBrowser browser, int index)
{
lock (lockObject)
{
browsers.Add(browser);
completedCount++;
Console.WriteLine($"浏览器 {index} 创建完成,总进度: {completedCount}/{totalCount}");
if (completedCount == totalCount)
{
Console.WriteLine("所有同步浏览器创建完成");
OnAllBrowsersCreated();
}
}
}
/// <summary>
/// 所有浏览器创建完成处理
/// </summary>
private void OnAllBrowsersCreated()
{
Console.WriteLine($"成功创建 {browsers.Count} 个同步浏览器");
// 可以在这里执行批量操作
ExecuteBatchOperations();
}
/// <summary>
/// 执行批量操作示例
/// </summary>
private void ExecuteBatchOperations()
{
for (int i = 0; i < browsers.Count; i++)
{
var browser = browsers[i];
if (browser.IsValid())
{
// 为每个浏览器设置不同的标题
string js = $@"document.title = '批量浏览器 {i + 1} - ' + document.title;";
browser.GetMainFrame().ExecuteJavaScript(js, "", 0);
}
}
}
/// <summary>
/// 获取所有创建的浏览器
/// </summary>
public List<FBroSharpBrowser> GetBrowsers()
{
lock (lockObject)
{
return new List<FBroSharpBrowser>(browsers);
}
}
}
/// <summary>
/// 批量创建浏览器任务
/// </summary>
public class BatchCreateBrowserTask : FBroSharpTask
{
private readonly string url;
private readonly int index;
private readonly BatchSyncBrowserCreator creator;
public BatchCreateBrowserTask(string url, int index, BatchSyncBrowserCreator creator)
{
this.url = url;
this.index = index;
this.creator = creator;
}
public override void Execute()
{
try
{
var windowsInfo = new FBroSharpWindowsInfo
{
parent_window = IntPtr.Zero, // 创建弹窗
x = 100 + (index * 50), // 错开窗口位置
y = 100 + (index * 50),
width = 800,
height = 600,
window_name = $"同步浏览器 {index}"
};
// 创建专用的事件处理器
var browserEvent = new SyncBrowserEvent(
onCreated: browser => {
Console.WriteLine($"批量同步浏览器 {index} 创建完成");
},
purpose: $"批量浏览器-{index}"
);
// 添加额外信息
var extraInfo = FBroSharpDictionaryValue.Create();
extraInfo.SetInt("batch_index", index);
extraInfo.SetString("batch_url", url);
extraInfo.SetString("creation_time", DateTime.Now.ToString());
FBroSharpBrowser browser = FBroSharpControl.CreateSync(
url,
windowsInfo,
default,
default,
extraInfo,
browserEvent,
default
);
if (browser != null && browser.IsValid())
{
browser.GetMainFrame().LoadURL(url);
// 通知创建完成
creator.OnBrowserCreated(browser, index);
}
else
{
Console.WriteLine($"批量创建浏览器 {index} 失败:返回无效实例");
}
}
catch (Exception ex)
{
Console.WriteLine($"批量创建浏览器 {index} 失败: {ex.Message}");
}
}
}带配置的同步创建
csharp
public class AdvancedSyncBrowserCreator
{
public static void CreateConfiguredBrowser(string url, BrowserConfig config)
{
var task = new ConfiguredBrowserTask(url, config);
bool result = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
if (!result)
{
throw new InvalidOperationException("无法投递浏览器创建任务到UI线程");
}
}
}
public class BrowserConfig
{
public string CachePath { get; set; }
public string ProxyUrl { get; set; }
public string ProxyUser { get; set; }
public string ProxyPassword { get; set; }
public double ZoomLevel { get; set; } = 0.0;
public bool IsPopup { get; set; } = false;
public int Width { get; set; } = 1200;
public int Height { get; set; } = 800;
public Dictionary<string, object> CustomProperties { get; set; } = new Dictionary<string, object>();
}
public class ConfiguredBrowserTask : FBroSharpTask
{
private readonly string url;
private readonly BrowserConfig config;
public ConfiguredBrowserTask(string url, BrowserConfig config)
{
this.url = url;
this.config = config;
}
public override void Execute()
{
try
{
// 设置窗口信息
var windowsInfo = new FBroSharpWindowsInfo
{
parent_window = config.IsPopup ? IntPtr.Zero : GetMainWindowHandle(),
width = config.Width,
height = config.Height,
window_name = $"配置浏览器 - {url}"
};
// 设置请求上下文(独立缓存)
FBroSharpRequestContext requestContext = null;
if (!string.IsNullOrEmpty(config.CachePath))
{
var contextSet = new FBroSharpRequestContextSet
{
cache_path = config.CachePath
};
requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
}
// 创建配置化的事件处理器
var browserEvent = new ConfiguredSyncBrowserEvent(config);
// 设置额外信息
var extraInfo = FBroSharpDictionaryValue.Create();
extraInfo.SetString("config_cache_path", config.CachePath ?? "default");
extraInfo.SetDouble("config_zoom_level", config.ZoomLevel);
extraInfo.SetBool("config_is_popup", config.IsPopup);
// 添加自定义属性
foreach (var prop in config.CustomProperties)
{
switch (prop.Value)
{
case string strValue:
extraInfo.SetString($"custom_{prop.Key}", strValue);
break;
case int intValue:
extraInfo.SetInt($"custom_{prop.Key}", intValue);
break;
case bool boolValue:
extraInfo.SetBool($"custom_{prop.Key}", boolValue);
break;
case double doubleValue:
extraInfo.SetDouble($"custom_{prop.Key}", doubleValue);
break;
}
}
// 同步创建浏览器
FBroSharpBrowser browser = FBroSharpControl.CreateSync(
url,
windowsInfo,
default,
requestContext,
extraInfo,
browserEvent,
default
);
if (browser != null && browser.IsValid())
{
browser.GetMainFrame().LoadURL(url);
Console.WriteLine($"配置浏览器创建成功: {url}");
}
else
{
Console.WriteLine($"配置浏览器创建失败: {url}");
}
}
catch (Exception ex)
{
Console.WriteLine($"配置浏览器创建失败: {ex.Message}");
}
}
private IntPtr GetMainWindowHandle()
{
// 获取主窗口句柄的逻辑
return Process.GetCurrentProcess().MainWindowHandle;
}
}
/// <summary>
/// 配置化的同步浏览器事件处理器
/// </summary>
public class ConfiguredSyncBrowserEvent : SyncBrowserEvent
{
private readonly BrowserConfig config;
public ConfiguredSyncBrowserEvent(BrowserConfig config) : base(purpose: "配置化浏览器")
{
this.config = config;
}
public override void OnAfterCreated(IFBroSharpBrowser browser, IFBroSharpDictionaryValue extrainfo)
{
base.OnAfterCreated(browser, extrainfo);
// 应用配置
ApplyConfiguration(browser);
}
/// <summary>
/// 应用浏览器配置
/// </summary>
private void ApplyConfiguration(IFBroSharpBrowser browser)
{
try
{
// 应用缩放级别
if (config.ZoomLevel != 0.0)
{
browser.SetZoomLevel(config.ZoomLevel);
}
// 应用代理设置
if (!string.IsNullOrEmpty(config.ProxyUrl))
{
if (!string.IsNullOrEmpty(config.ProxyUser))
{
browser.SetProxy(config.ProxyUrl, config.ProxyUser, config.ProxyPassword);
}
else
{
browser.SetProxy(config.ProxyUrl);
}
}
Console.WriteLine($"浏览器配置已应用: ID={browser.GetIdentifier()}");
// 注入配置信息到页面
string configJS = $@"
window.FBroConfig = {{
zoomLevel: {config.ZoomLevel},
isPopup: {config.IsPopup.ToString().ToLower()},
cachePath: '{config.CachePath ?? "default"}',
customProperties: {Newtonsoft.Json.JsonConvert.SerializeObject(config.CustomProperties)}
}};
console.log('FBro配置已注入:', window.FBroConfig);
";
browser.GetMainFrame().ExecuteJavaScript(configJS, "", 0);
}
catch (Exception ex)
{
Console.WriteLine($"应用浏览器配置失败: {ex.Message}");
}
}
}方法参数说明
FBroSharpTaskRunner.CefPostTask
语法:
csharp
bool CefPostTask(FBroSharpThreadID threadId, FBroSharpTask task)参数:
| 参数 | 类型 | 说明 |
|---|---|---|
threadId | FBroSharpThreadID | 目标线程ID,同步创建使用TID_UI |
task | FBroSharpTask | 要执行的任务实例 |
返回值:
| 类型 | 说明 |
|---|---|
bool | true表示任务投递成功,false表示投递失败 |
FBroSharpControl.CreateSync
语法:
csharp
FBroSharpBrowser CreateSync(
string url,
FBroSharpWindowsInfo windowsInfo,
FBroSharpBrowserSetting browserSetting,
FBroSharpRequestContext requestContext,
FBroSharpDictionaryValue extraInfo,
FBroSharpBrowserEvent browserEvent,
FBroSharpEventDisableControl eventDisableControl,
string user_flag
)参数:
| 参数 | 类型 | 说明 |
|---|---|---|
url | string | 初始加载的URL |
windowsInfo | FBroSharpWindowsInfo | 窗口信息配置 |
browserSetting | FBroSharpBrowserSetting | 浏览器设置(可选) |
requestContext | FBroSharpRequestContext | 请求上下文(可选) |
extraInfo | FBroSharpDictionaryValue | 额外参数(可选) |
browserEvent | FBroSharpBrowserEvent | 浏览器事件回调 |
eventDisableControl | FBroSharpEventDisableControl | 事件禁用控制(可选) |
user_flag | string | 用户自定义浏览器标识符(可选) |
返回值:
| 类型 | 说明 |
|---|---|
FBroSharpBrowser | 创建成功的浏览器实例 |
user_flag在同步创建中的应用
同步创建中的标识管理
同步创建浏览器时,user_flag参数特别重要,因为它能让您立即标识和管理创建的浏览器实例:
csharp
/// <summary>
/// 同步创建带标识的浏览器任务
/// </summary>
public class SyncCreateBrowserWithFlagTask : FBroSharpTask
{
private readonly string url;
private readonly string userFlag;
private readonly FBroSharpWindowsInfo windowsInfo;
private readonly Action<FBroSharpBrowser, string> onSuccess;
private readonly Action<string, Exception> onError;
public SyncCreateBrowserWithFlagTask(
string url,
string userFlag,
FBroSharpWindowsInfo windowsInfo,
Action<FBroSharpBrowser, string> onSuccess = null,
Action<string, Exception> onError = null)
{
this.url = url;
this.userFlag = userFlag;
this.windowsInfo = windowsInfo;
this.onSuccess = onSuccess;
this.onError = onError;
}
public override void Execute()
{
try
{
// 创建额外信息,包含user_flag
var extraInfo = FBroSharpDictionaryValue.Create();
extraInfo.SetString("sync_user_flag", userFlag);
extraInfo.SetString("sync_created_time", DateTime.Now.ToString());
extraInfo.SetBool("is_sync_created", true);
// 创建同步浏览器事件处理器
var browserEvent = new SyncBrowserEvent(
onCreated: browser => {
Console.WriteLine($"同步浏览器创建成功: {userFlag}");
onSuccess?.Invoke(browser, userFlag);
},
onClosed: browser => {
Console.WriteLine($"同步浏览器已关闭: {userFlag}");
},
purpose: $"同步浏览器-{userFlag}"
);
// 同步创建浏览器,指定user_flag
FBroSharpBrowser browser = FBroSharpControl.CreateSync(
url,
windowsInfo,
default,
default,
extraInfo,
browserEvent,
default,
userFlag // 关键:指定用户标识
);
if (browser != null && browser.IsValid())
{
browser.GetMainFrame().LoadURL(url);
Console.WriteLine($"同步创建浏览器成功,标识: {userFlag},ID: {browser.GetIdentifier()}");
// 立即验证标识是否可用
var retrievedBrowser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
if (retrievedBrowser != null && retrievedBrowser.IsSame(browser))
{
Console.WriteLine($"标识验证成功: {userFlag}");
}
else
{
Console.WriteLine($"警告:标识验证失败: {userFlag}");
}
}
else
{
throw new InvalidOperationException($"同步创建浏览器失败,返回无效实例: {userFlag}");
}
}
catch (Exception ex)
{
Console.WriteLine($"同步创建浏览器异常: {userFlag} - {ex.Message}");
onError?.Invoke(userFlag, ex);
}
}
}同步批量创建管理器
csharp
/// <summary>
/// 同步批量创建浏览器管理器
/// 专门用于同步创建场景下的浏览器管理
/// </summary>
public class SyncBatchBrowserManager
{
private readonly Dictionary<string, SyncBrowserInfo> syncBrowsers = new Dictionary<string, SyncBrowserInfo>();
private readonly object lockObject = new object();
public class SyncBrowserInfo
{
public string UserFlag { get; set; }
public FBroSharpBrowser Browser { get; set; }
public string Purpose { get; set; }
public DateTime CreatedTime { get; set; }
public string InitialUrl { get; set; }
public bool IsCreated { get; set; }
public Exception CreationError { get; set; }
}
/// <summary>
/// 批量同步创建浏览器
/// </summary>
/// <param name="browserConfigs">浏览器配置列表</param>
/// <returns>创建成功的浏览器数量</returns>
public int BatchCreateSync(List<(string url, string userFlag, string purpose)> browserConfigs)
{
int successCount = 0;
var tasks = new List<SyncCreateBrowserWithFlagTask>();
// 准备所有任务
for (int i = 0; i < browserConfigs.Count; i++)
{
var config = browserConfigs[i];
// 确保user_flag唯一
string uniqueFlag = $"{config.userFlag}_{DateTime.Now:yyyyMMddHHmmssffff}_{i}";
var windowsInfo = new FBroSharpWindowsInfo
{
parent_window = IntPtr.Zero,
x = 100 + (i * 60),
y = 100 + (i * 60),
width = 1000,
height = 700,
window_name = $"同步浏览器-{config.purpose}"
};
// 记录浏览器信息
lock (lockObject)
{
syncBrowsers[uniqueFlag] = new SyncBrowserInfo
{
UserFlag = uniqueFlag,
Purpose = config.purpose,
InitialUrl = config.url,
CreatedTime = DateTime.Now,
IsCreated = false
};
}
var task = new SyncCreateBrowserWithFlagTask(
config.url,
uniqueFlag,
windowsInfo,
onSuccess: (browser, flag) => {
lock (lockObject)
{
if (syncBrowsers.ContainsKey(flag))
{
syncBrowsers[flag].Browser = browser;
syncBrowsers[flag].IsCreated = true;
}
}
Interlocked.Increment(ref successCount);
},
onError: (flag, error) => {
lock (lockObject)
{
if (syncBrowsers.ContainsKey(flag))
{
syncBrowsers[flag].CreationError = error;
}
}
}
);
tasks.Add(task);
}
// 顺序投递任务到UI线程
foreach (var task in tasks)
{
bool posted = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
if (!posted)
{
Console.WriteLine("任务投递失败");
}
// 添加小延迟避免同时创建过多浏览器
System.Threading.Thread.Sleep(100);
}
// 等待所有任务完成(简单实现,实际项目中可使用更复杂的同步机制)
int maxWaitTime = 30000; // 30秒超时
int waited = 0;
while (successCount + GetErrorCount() < browserConfigs.Count && waited < maxWaitTime)
{
System.Threading.Thread.Sleep(100);
waited += 100;
}
Console.WriteLine($"批量同步创建完成: 成功 {successCount}/{browserConfigs.Count}");
PrintCreationSummary();
return successCount;
}
/// <summary>
/// 通过标识获取同步创建的浏览器
/// </summary>
/// <param name="userFlag">用户标识</param>
/// <returns>浏览器实例</returns>
public FBroSharpBrowser GetSyncBrowser(string userFlag)
{
lock (lockObject)
{
if (syncBrowsers.ContainsKey(userFlag) && syncBrowsers[userFlag].IsCreated)
{
return syncBrowsers[userFlag].Browser;
}
}
// 从全局列表中获取
return FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
}
/// <summary>
/// 批量操作同步创建的浏览器
/// </summary>
/// <param name="action">操作函数</param>
public void BatchOperateSync(Action<FBroSharpBrowser, SyncBrowserInfo> action)
{
List<SyncBrowserInfo> browserList;
lock (lockObject)
{
browserList = syncBrowsers.Values.Where(info => info.IsCreated).ToList();
}
foreach (var info in browserList)
{
try
{
if (info.Browser != null && info.Browser.IsValid())
{
action(info.Browser, info);
}
}
catch (Exception ex)
{
Console.WriteLine($"批量操作失败: {info.UserFlag} - {ex.Message}");
}
}
}
/// <summary>
/// 设置所有同步浏览器的标题
/// </summary>
/// <param name="titlePrefix">标题前缀</param>
public void SetAllBrowserTitles(string titlePrefix)
{
BatchOperateSync((browser, info) =>
{
string jsCode = $@"
document.title = '{titlePrefix} - {info.Purpose} - ' + document.title;
console.log('同步浏览器标题已更新: {info.UserFlag}');
";
browser.GetMainFrame().ExecuteJavaScript(jsCode, "", 0);
});
}
/// <summary>
/// 关闭所有同步创建的浏览器
/// </summary>
public void CloseAllSyncBrowsers()
{
BatchOperateSync((browser, info) =>
{
Console.WriteLine($"关闭同步浏览器: {info.Purpose} ({info.UserFlag})");
browser.CloseBrowser(true);
});
lock (lockObject)
{
syncBrowsers.Clear();
}
}
/// <summary>
/// 获取创建错误的数量
/// </summary>
/// <returns>错误数量</returns>
private int GetErrorCount()
{
lock (lockObject)
{
return syncBrowsers.Values.Count(info => info.CreationError != null);
}
}
/// <summary>
/// 打印创建摘要
/// </summary>
private void PrintCreationSummary()
{
lock (lockObject)
{
int total = syncBrowsers.Count;
int success = syncBrowsers.Values.Count(info => info.IsCreated);
int errors = syncBrowsers.Values.Count(info => info.CreationError != null);
int pending = total - success - errors;
Console.WriteLine($"\n=== 同步创建浏览器摘要 ===");
Console.WriteLine($"总数: {total}");
Console.WriteLine($"成功: {success}");
Console.WriteLine($"失败: {errors}");
Console.WriteLine($"等待: {pending}");
// 显示错误详情
var errorBrowsers = syncBrowsers.Values.Where(info => info.CreationError != null).ToList();
if (errorBrowsers.Any())
{
Console.WriteLine("\n失败详情:");
foreach (var info in errorBrowsers)
{
Console.WriteLine($" {info.UserFlag}: {info.CreationError.Message}");
}
}
Console.WriteLine("========================\n");
}
}
/// <summary>
/// 获取统计信息
/// </summary>
/// <returns>统计字典</returns>
public Dictionary<string, object> GetStatistics()
{
lock (lockObject)
{
return new Dictionary<string, object>
{
["total"] = syncBrowsers.Count,
["success"] = syncBrowsers.Values.Count(info => info.IsCreated),
["errors"] = syncBrowsers.Values.Count(info => info.CreationError != null),
["pending"] = syncBrowsers.Values.Count(info => !info.IsCreated && info.CreationError == null),
["flags"] = syncBrowsers.Keys.ToList()
};
}
}
}使用示例
csharp
// 使用同步批量创建管理器
private void UseSyncBatchManager()
{
var manager = new SyncBatchBrowserManager();
// 准备浏览器配置
var configs = new List<(string url, string userFlag, string purpose)>
{
("https://www.baidu.com", "search_baidu", "搜索测试"),
("https://www.bing.com", "search_bing", "搜索对比"),
("https://www.github.com", "dev_github", "开发工具"),
("https://www.stackoverflow.com", "dev_stackoverflow", "技术支持")
};
// 批量同步创建
int successCount = manager.BatchCreateSync(configs);
if (successCount > 0)
{
// 等待片刻让浏览器完全加载
System.Threading.Thread.Sleep(2000);
// 设置所有浏览器标题
manager.SetAllBrowserTitles("FBro同步测试");
// 通过标识获取特定浏览器进行操作
var allFlags = manager.GetStatistics()["flags"] as List<string>;
var baiduFlag = allFlags?.FirstOrDefault(f => f.Contains("search_baidu"));
if (!string.IsNullOrEmpty(baiduFlag))
{
var baiduBrowser = manager.GetSyncBrowser(baiduFlag);
if (baiduBrowser != null)
{
// 在百度浏览器中执行搜索
string searchJS = @"
var searchInput = document.querySelector('#kw');
if (searchInput) {
searchInput.value = 'FBro浏览器测试';
searchInput.form.submit();
}
";
baiduBrowser.GetMainFrame().ExecuteJavaScript(searchJS, "", 0);
Console.WriteLine($"已在百度浏览器中执行搜索: {baiduFlag}");
}
}
// 批量操作所有GitHub相关浏览器
manager.BatchOperateSync((browser, info) =>
{
if (info.UserFlag.Contains("github"))
{
string githubJS = @"
document.body.style.border = '3px solid #28a745';
console.log('GitHub浏览器已标记: " + info.UserFlag + @"');
";
browser.GetMainFrame().ExecuteJavaScript(githubJS, "", 0);
}
});
// 打印统计信息
var stats = manager.GetStatistics();
Console.WriteLine($"同步创建统计: {Newtonsoft.Json.JsonConvert.SerializeObject(stats, Newtonsoft.Json.Formatting.Indented)}");
// 演示标识验证
foreach (var flag in allFlags ?? new List<string>())
{
var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(flag);
if (browser != null)
{
Console.WriteLine($"验证成功 - 标识: {flag}, 浏览器ID: {browser.GetIdentifier()}");
}
}
}
else
{
Console.WriteLine("没有成功创建任何同步浏览器");
}
}
/// <summary>
/// 演示单个同步浏览器的完整创建和管理流程
/// </summary>
private void DemonstrateCompleteSyncFlow()
{
// 1. 生成标识
string userFlag = SyncBrowserFlagGenerator.GenerateSyncFlag("demo", "complete");
Console.WriteLine($"生成的同步标识: {userFlag}");
// 2. 创建监控器
var monitor = new SyncCreationMonitor();
// 3. 配置窗口信息
var windowsInfo = new FBroSharpWindowsInfo
{
parent_window = IntPtr.Zero,
x = 200,
y = 200,
width = 1000,
height = 700,
window_name = $"完整流程演示-{userFlag}"
};
// 4. 创建增强任务
var task = new EnhancedSyncCreateTask(
"https://www.example.com",
userFlag,
windowsInfo,
monitor,
onSuccess: (browser, flag) =>
{
Console.WriteLine($"浏览器创建成功回调: {flag}");
// 立即验证和操作
if (SyncFlagValidator.ValidateSyncCreatedBrowser(browser, flag))
{
// 注入测试脚本
string testJS = @"
console.log('完整流程演示浏览器已就绪');
document.title = '完整流程演示 - " + flag + @"';
// 添加成功标记
var successDiv = document.createElement('div');
successDiv.innerHTML = '✅ FBro同步创建成功<br>标识: " + flag + @"';
successDiv.style.cssText = 'position:fixed;top:10px;right:10px;background:#4CAF50;color:white;padding:15px;border-radius:8px;z-index:9999;font-family:Arial;';
document.body.appendChild(successDiv);
";
browser.GetMainFrame().ExecuteJavaScript(testJS, "", 0);
}
},
onError: (flag, error) =>
{
Console.WriteLine($"浏览器创建失败回调: {flag} - {error.Message}");
}
);
// 5. 投递任务
bool posted = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
if (posted)
{
Console.WriteLine("完整流程演示任务已投递");
// 6. 等待并检查结果
System.Threading.Thread.Sleep(3000);
var stats = monitor.GetStatistics();
Console.WriteLine(stats.ToString());
// 7. 验证浏览器是否可通过标识获取
var retrievedBrowser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
if (retrievedBrowser != null && retrievedBrowser.IsValid())
{
Console.WriteLine($"✅ 完整流程演示成功 - 浏览器可通过标识 {userFlag} 获取");
}
else
{
Console.WriteLine($"❌ 完整流程演示失败 - 无法通过标识 {userFlag} 获取浏览器");
}
}
else
{
Console.WriteLine("完整流程演示任务投递失败");
}
}
## 线程ID说明
| 线程ID | 说明 |
|--------|------|
| `TID_UI` | UI线程,用于同步创建浏览器 |
| `TID_IO` | IO线程,处理网络请求 |
| `TID_FILE` | 文件线程,处理文件操作 |
| `TID_RENDERER` | 渲染线程,处理页面渲染 |
## 使用注意事项
### 1. 线程安全
- **UI线程要求**:同步创建必须在UI线程中执行
- **任务投递**:使用`CefPostTask`确保在正确的线程中执行
- **避免阻塞**:不要在主线程中直接调用同步创建
### 2. 错误处理
```csharp
public override void Execute()
{
try
{
FBroSharpBrowser browser = FBroSharpControl.CreateSync(/* 参数 */);
// 验证浏览器实例
if (browser == null || !browser.IsValid())
{
Console.WriteLine("同步创建返回无效的浏览器实例");
return;
}
// 成功处理逻辑
Console.WriteLine($"同步创建成功: {browser.GetIdentifier()}");
}
catch (Exception ex)
{
// 记录错误日志
Console.WriteLine($"同步创建失败: {ex.Message}");
// 可以在这里添加重试逻辑或通知机制
NotifyCreationFailed(ex);
}
}3. 资源管理
csharp
public override void Execute()
{
FBroSharpRequestContext requestContext = null;
try
{
// 创建资源
requestContext = CreateRequestContext();
FBroSharpBrowser browser = FBroSharpControl.CreateSync(/* 参数 */);
// 使用浏览器
if (browser != null && browser.IsValid())
{
// 执行操作
}
}
finally
{
// 清理资源
requestContext?.Dispose();
}
}最佳实践
- 任务封装:将创建逻辑封装在自定义任务类中
- 错误处理:始终包含try-catch进行异常处理
- 参数验证:在Execute方法中验证必要参数
- 实例验证:检查返回的浏览器实例是否有效
- 资源释放:正确管理创建的资源对象
- 状态跟踪:对于批量创建,实现进度跟踪机制
- 事件处理器优化:为同步创建场景创建专门的事件处理器
- 同步标识管理:在同步创建场景下合理使用user_flag进行浏览器管理
同步创建中的user_flag最佳实践
1. 立即验证机制
csharp
/// <summary>
/// 同步创建后立即验证user_flag
/// </summary>
public static class SyncFlagValidator
{
/// <summary>
/// 验证同步创建的浏览器标识
/// </summary>
/// <param name="browser">创建的浏览器实例</param>
/// <param name="userFlag">预期的用户标识</param>
/// <returns>验证结果</returns>
public static bool ValidateSyncCreatedBrowser(FBroSharpBrowser browser, string userFlag)
{
if (browser == null || !browser.IsValid())
{
Console.WriteLine($"同步创建验证失败:浏览器实例无效 ({userFlag})");
return false;
}
// 尝试通过标识获取浏览器
var retrievedBrowser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
if (retrievedBrowser == null)
{
Console.WriteLine($"同步创建验证失败:无法通过标识获取浏览器 ({userFlag})");
return false;
}
// 验证是否为同一浏览器实例
if (!browser.IsSame(retrievedBrowser))
{
Console.WriteLine($"同步创建验证失败:浏览器实例不匹配 ({userFlag})");
return false;
}
Console.WriteLine($"同步创建验证成功:{userFlag}");
return true;
}
}2. 同步创建专用标识生成器
csharp
/// <summary>
/// 同步创建专用的标识生成器
/// </summary>
public static class SyncBrowserFlagGenerator
{
private static int syncCounter = 0;
private static readonly object counterLock = new object();
/// <summary>
/// 生成同步创建专用标识
/// </summary>
/// <param name="purpose">用途</param>
/// <param name="category">分类</param>
/// <returns>同步标识</returns>
public static string GenerateSyncFlag(string purpose, string category = "sync")
{
lock (counterLock)
{
syncCounter++;
string timestamp = DateTime.Now.ToString("yyyyMMddHHmmssffff");
return $"sync_{category}_{purpose}_{timestamp}_{syncCounter:D4}".ToLower();
}
}
/// <summary>
/// 生成批量同步标识
/// </summary>
/// <param name="batchId">批次ID</param>
/// <param name="index">索引</param>
/// <param name="purpose">用途</param>
/// <returns>批量同步标识</returns>
public static string GenerateBatchSyncFlag(string batchId, int index, string purpose)
{
string timestamp = DateTime.Now.ToString("yyyyMMddHHmmssffff");
return $"batch_{batchId}_{purpose}_{timestamp}_{index:D3}".ToLower();
}
/// <summary>
/// 重置计数器(测试用)
/// </summary>
public static void ResetCounter()
{
lock (counterLock)
{
syncCounter = 0;
}
}
}3. 同步创建状态监控
csharp
/// <summary>
/// 同步创建状态监控器
/// </summary>
public class SyncCreationMonitor
{
private readonly Dictionary<string, SyncCreationStatus> creationStatuses = new Dictionary<string, SyncCreationStatus>();
private readonly object lockObject = new object();
public class SyncCreationStatus
{
public string UserFlag { get; set; }
public DateTime StartTime { get; set; }
public DateTime? CompletedTime { get; set; }
public bool IsSuccess { get; set; }
public Exception Error { get; set; }
public FBroSharpBrowser Browser { get; set; }
public TimeSpan? Duration => CompletedTime?.Subtract(StartTime);
}
/// <summary>
/// 开始监控同步创建
/// </summary>
/// <param name="userFlag">用户标识</param>
public void StartMonitoring(string userFlag)
{
lock (lockObject)
{
creationStatuses[userFlag] = new SyncCreationStatus
{
UserFlag = userFlag,
StartTime = DateTime.Now
};
}
}
/// <summary>
/// 完成监控(成功)
/// </summary>
/// <param name="userFlag">用户标识</param>
/// <param name="browser">创建的浏览器</param>
public void CompleteSuccess(string userFlag, FBroSharpBrowser browser)
{
lock (lockObject)
{
if (creationStatuses.ContainsKey(userFlag))
{
var status = creationStatuses[userFlag];
status.CompletedTime = DateTime.Now;
status.IsSuccess = true;
status.Browser = browser;
}
}
}
/// <summary>
/// 完成监控(失败)
/// </summary>
/// <param name="userFlag">用户标识</param>
/// <param name="error">错误信息</param>
public void CompleteError(string userFlag, Exception error)
{
lock (lockObject)
{
if (creationStatuses.ContainsKey(userFlag))
{
var status = creationStatuses[userFlag];
status.CompletedTime = DateTime.Now;
status.IsSuccess = false;
status.Error = error;
}
}
}
/// <summary>
/// 获取创建统计
/// </summary>
/// <returns>统计信息</returns>
public CreationStatistics GetStatistics()
{
lock (lockObject)
{
var stats = new CreationStatistics();
stats.TotalCount = creationStatuses.Count;
stats.SuccessCount = creationStatuses.Values.Count(s => s.IsSuccess);
stats.ErrorCount = creationStatuses.Values.Count(s => s.CompletedTime.HasValue && !s.IsSuccess);
stats.PendingCount = creationStatuses.Values.Count(s => !s.CompletedTime.HasValue);
if (stats.SuccessCount > 0)
{
var successfulCreations = creationStatuses.Values.Where(s => s.IsSuccess && s.Duration.HasValue);
stats.AverageCreationTime = TimeSpan.FromMilliseconds(
successfulCreations.Average(s => s.Duration.Value.TotalMilliseconds)
);
}
return stats;
}
}
public class CreationStatistics
{
public int TotalCount { get; set; }
public int SuccessCount { get; set; }
public int ErrorCount { get; set; }
public int PendingCount { get; set; }
public TimeSpan AverageCreationTime { get; set; }
public double SuccessRate => TotalCount > 0 ? (double)SuccessCount / TotalCount * 100 : 0;
public override string ToString()
{
return $@"
=== 同步创建统计 ===
总数: {TotalCount}
成功: {SuccessCount}
失败: {ErrorCount}
等待: {PendingCount}
成功率: {SuccessRate:F2}%
平均创建时间: {AverageCreationTime.TotalMilliseconds:F0}ms
==================";
}
}
}4. 增强的同步创建任务
csharp
/// <summary>
/// 增强版同步创建任务,包含完整的user_flag管理
/// </summary>
public class EnhancedSyncCreateTask : FBroSharpTask
{
private readonly string url;
private readonly string userFlag;
private readonly FBroSharpWindowsInfo windowsInfo;
private readonly SyncCreationMonitor monitor;
private readonly Action<FBroSharpBrowser, string> onSuccess;
private readonly Action<string, Exception> onError;
public EnhancedSyncCreateTask(
string url,
string userFlag,
FBroSharpWindowsInfo windowsInfo,
SyncCreationMonitor monitor = null,
Action<FBroSharpBrowser, string> onSuccess = null,
Action<string, Exception> onError = null)
{
this.url = url;
this.userFlag = userFlag;
this.windowsInfo = windowsInfo;
this.monitor = monitor;
this.onSuccess = onSuccess;
this.onError = onError;
}
public override void Execute()
{
// 开始监控
monitor?.StartMonitoring(userFlag);
try
{
// 预验证标识
var validation = BrowserFlagValidator.ValidateFlag(userFlag);
if (!validation.IsValid)
{
throw new ArgumentException($"标识格式无效: {string.Join(", ", validation.Errors)}");
}
// 确保标识唯一
if (!BrowserFlagManager.IsUnique(userFlag))
{
throw new InvalidOperationException($"标识已存在: {userFlag}");
}
// 创建额外信息
var extraInfo = FBroSharpDictionaryValue.Create();
extraInfo.SetString("sync_user_flag", userFlag);
extraInfo.SetString("sync_created_time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
extraInfo.SetBool("is_sync_created", true);
extraInfo.SetString("sync_url", url);
// 创建事件处理器
var browserEvent = new EnhancedSyncBrowserEvent(userFlag, url);
// 同步创建浏览器
Console.WriteLine($"开始同步创建浏览器: {userFlag}");
FBroSharpBrowser browser = FBroSharpControl.CreateSync(
url,
windowsInfo,
default,
default,
extraInfo,
browserEvent,
default,
userFlag
);
// 验证创建结果
if (browser == null || !browser.IsValid())
{
throw new InvalidOperationException($"同步创建返回无效浏览器实例: {userFlag}");
}
// 立即验证标识
if (!SyncFlagValidator.ValidateSyncCreatedBrowser(browser, userFlag))
{
throw new InvalidOperationException($"同步创建标识验证失败: {userFlag}");
}
// 加载URL
browser.GetMainFrame().LoadURL(url);
// 成功回调
Console.WriteLine($"同步创建浏览器成功: {userFlag} (ID: {browser.GetIdentifier()})");
monitor?.CompleteSuccess(userFlag, browser);
onSuccess?.Invoke(browser, userFlag);
}
catch (Exception ex)
{
Console.WriteLine($"同步创建浏览器失败: {userFlag} - {ex.Message}");
monitor?.CompleteError(userFlag, ex);
onError?.Invoke(userFlag, ex);
}
}
}
/// <summary>
/// 增强版同步浏览器事件处理器
/// </summary>
public class EnhancedSyncBrowserEvent : SyncBrowserEvent
{
private readonly string userFlag;
private readonly string originalUrl;
public EnhancedSyncBrowserEvent(string userFlag, string originalUrl)
: base(purpose: $"增强同步-{userFlag}")
{
this.userFlag = userFlag;
this.originalUrl = originalUrl;
}
public override void OnAfterCreated(IFBroSharpBrowser browser, IFBroSharpDictionaryValue extrainfo)
{
base.OnAfterCreated(browser, extrainfo);
// 注入增强信息
string enhancedJS = $@"
window.FBroSyncEnhanced = {{
userFlag: '{userFlag}',
originalUrl: '{originalUrl}',
createdTime: '{DateTime.Now:yyyy-MM-dd HH:mm:ss}',
browserId: {browser.GetIdentifier()},
isEnhancedSync: true,
// 实用工具函数
getInfo: function() {{
return {{
flag: this.userFlag,
url: this.originalUrl,
created: this.createdTime,
id: this.browserId
}};
}},
logInfo: function() {{
console.log('FBro增强同步浏览器信息:', this.getInfo());
}}
}};
// 自动记录信息
window.FBroSyncEnhanced.logInfo();
";
browser.GetMainFrame().ExecuteJavaScript(enhancedJS, "", 0);
}
}与异步创建的对比
| 特性 | 同步创建 | 异步创建 |
|---|---|---|
| 执行线程 | 必须在UI线程 | 任意线程 |
| 返回方式 | 立即返回浏览器实例 | 通过回调获取 |
| 复杂度 | 需要任务投递机制 | 直接调用 |
| 适用场景 | 需要立即使用浏览器 | 一般创建场景 |
| 性能影响 | 可能阻塞UI线程 | 不阻塞主线程 |
| 错误处理 | 可立即捕获异常 | 通过事件处理 |
实际应用场景
- 自动化测试:需要批量创建多个浏览器进行并行测试
- 数据采集:同时打开多个页面进行数据抓取
- 监控系统:创建多个浏览器监控不同网站
- 演示程序:需要精确控制浏览器创建时机的演示应用
- 开发调试:快速创建测试浏览器进行功能验证