CEFSharp应用程序显示空白屏幕,然后在一分钟后自行响应



我一直在开发一款应用程序,该应用程序使用CEFSharp(83.4.20版本(加载我公司的VOIP平台(engage.ringcenter.com(https://github.com/dylanlangston/EngageRC

该应用程序已经运行了大约一个月,在投入生产后,我收到了一个奇怪问题的报告。人们看到一个空白屏幕,无法与网页交互(问题示例(。几分钟后,问题似乎自行解决,他们能够再次与网页互动。我自己还没能重现这个问题。

我认为这可能是渲染问题。到目前为止,我已经尝试在我的应用程序中调整以下内容:

拆下下面的管路。

settings.CefCommandLineArgs.Add("disable-gpu");
settings.CefCommandLineArgs.Add("disable-gpu-shader-disk-cache", "1");

将它们替换为。

settings.CefCommandLineArgs.Add("disable-gpu-compositing");

不幸的是,这并没有解决问题,我不确定我错过了什么。

CEF初始化的相关代码位于https://github.com/dylanlangston/EngageRC/blob/master/Windows/MainWindow.Designer.cs在InitializeChromium方法下。见下文

// 
// Chrome
// 
private CefSharp.WinForms.ChromiumWebBrowser chromeBrowser;
public ChromiumWebBrowser InitializeChromium(string URL, string Name)
{
// Check if already Initialized
if (Cef.IsInitialized == false)
{
CefSettings settings = new CefSettings();
// Enable Logging if debugging or console window
if (!this.debug || !this.console)
{
settings.LogSeverity = LogSeverity.Disable;
}
else
{
settings.LogSeverity = LogSeverity.Verbose;
}
// Enable Microphone settings
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
// Set Custom Browser Paths
settings.CefCommandLineArgs.Add("disable-gpu-shader-disk-cache", "1");
// Disable GPU to fix rendering issues on some machines.
settings.CefCommandLineArgs.Add("disable-gpu");
// Disable CORS protection (cross site scripting) which the engage.ringcentral.com site doesn't seem to like/respect, disabled as the website doesn't seem to improve with this turned on.
//settings.CefCommandLineArgs.Add("disable-web-security");
// Enable session Cookie persistence, disabled as it's unneeded. 
//settings.PersistSessionCookies = true;
// Custom Browser paths
settings.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCEFSharpCefSharp.BrowserSubprocess.exe");
settings.LocalesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCEFSharplocales");
settings.ResourcesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCEFSharp");
// Check if Resources folder is writable. If it isn't then write to application data.
DirectoryInfo di = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCEFSharp"));
if ((di.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
settings.RootCachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRCCEFSharpcache");
settings.CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRCCEFSharpcache");
settings.LogFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRCCEFSharpdebug.log");
}
else
{
settings.RootCachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCEFSharpcache");
settings.CachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCEFSharpcache");
settings.LogFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCEFSharpdebug.log");
}
// Initialize cef with the provided settings or add new tab
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
}
// Create a browser component
chromeBrowser = new ChromiumWebBrowser(URL);
// Set Name
chromeBrowser.Name = Name;
// Adjust size and scaling
this.chromeBrowser.Dock = DockStyle.Fill;
this.chromeBrowser.Width = this.Width;
this.chromeBrowser.Height = this.Height;
// Add control
this.Controls.Add(chromeBrowser);
// Bring to front
this.chromeBrowser.BringToFront();
// Set label to Goodbye.
this.label1.Text = "Goodbye";
// Return control
return chromeBrowser;
}

我之前在谷歌上找不到任何问题,所以这似乎不是其他人看到的应用程序。当谈到C#时,我仍在学习诀窍,所以这100%可能是我自己的错,我做错了什么。

我能够从一台遇到该问题的机器上获得详细的日志记录。我主要看到以下错误。完整日志位于https://gist.github.com/dylanlangston/194e389ead437e6c6fe08b2d4746bf43

[0729/08366.491:错误:paint_controller.cc(646(]PaintController::FinishCycle((完成

如有任何想法或建议可帮助解决此问题,我们将不胜感激!


更新:根据@amaitland的有用评论,这种行为似乎是由使用线程引起的。在我不应该的线程上睡觉。

在查看了我的代码之后,看起来我在两个位置都有这个。

首先,我调用thread.sleep,等待浏览器缩放级别与我保存到windows隔离存储中的值相匹配。除非应用程序第一次启动,否则不应该运行此程序。我不认为这是问题所在,但为了安全起见,我会把它贴在这里。(https://github.com/dylanlangston/EngageRC/blob/master/CEFSharpHandlers.cs)

public void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
{
ChromiumWebBrowser chrome = (ChromiumWebBrowser)sender;
if (!args.IsLoading) // Loading finished.
{
// If first load set zoom level to previous level
if (firstLoad < 3)
{
try
{
double zoom = double.Parse(ConfigReader.ReadIsolatedStorage("z"), System.Globalization.CultureInfo.InvariantCulture);
while (args.Browser.GetZoomLevelAsync().Result != zoom) { chrome.SetZoomLevel(zoom); Thread.Sleep(50); }
}
catch { }
firstLoad++;
}
// These JS and CSS modifications built into EngageRC
string hotfixJS = "";
string hotfixCSS = "/* Fix for dropdowns */ ul.dropdown-menu[style=\"opacity: 1;\"] {display: block !important; } /* End fix for dropdowns */";
// Inject custom javascript and css code on page load
chrome.ExecuteScriptAsync(hotfixJS);
chrome.ExecuteScriptAsync("var engageRCSS = document.getElementById('EngageRCSS'); if (!engageRCSS) { var node = document.createElement('style'); node.setAttribute('id', 'EngageRCSS'); node.innerHTML = "" + hotfixCSS +""; document.body.appendChild(node); }");
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCustom.js"))) { chrome.ExecuteScriptAsync(System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCustom.js"))); }
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCustom.css"))) { chrome.ExecuteScriptAsync("var customCSS = document.getElementById('customcss'); if (!customCSS) { var node = document.createElement('style'); node.setAttribute('id', 'customcss'); node.innerHTML = "" + System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"ResourcesCustom.css")).Replace("n", String.Empty).Replace("r", String.Empty).Replace("t", String.Empty).Replace(""", "\"") + ""; document.body.appendChild(node); }"); }
}
}

我在显示通知时也有它。这很可能是我的问题,因为它在主应用程序线程中运行。。。(https://github.com/dylanlangston/EngageRC/blob/master/NotificationSupport.cs)

public void displayNotification(string Title = "EngageRC", string Message = "")
{
// Display notification for 5 seconds
Notify notification = MainWindow.notification;
try
{
if (!IsActive(hWnd)) // Check if application is already active.
{
string config = ConfigReader.GetConfigValue("NotificationsDisabled").ToLower();
if (!(config == "true" || config == "1"))
{
notification.NewNotification(Title, Message, 5000);
}
config = ConfigReader.GetConfigValue("GetFocusOnCallDisabled").ToLower();
if (!(config == "true" || config == "1") && (Message == "You have incoming call"))
{
// Minimize window
ShowWindow(hWnd, 0x02);
// Restore window to previous state.
ShowWindow(hWnd, 0x09);
}
config = ConfigReader.GetConfigValue("GetFocusOnPendingDispositionDisabled").ToLower();
if (!(config == "true" || config == "1") && (Message == "You have a disposition pending"))
{
// Minimize window
ShowWindow(hWnd, 0x02);
// Restore window to previous state.
ShowWindow(hWnd, 0x09);
}
}
}
catch { notification.SetIconVisible(false); }
finally
{
Thread.Sleep(4999);
notification.SetIconVisible(false);
}
}

根据我所听到的,我应该让NotificationForm在与主应用程序不同的线程上运行吗?还是我偏离了基地?


更新:我能够将通知移动到它自己的线程中。我正在关闭这个问题,并将进行用户测试,看看空白屏幕是否仍然存在。

再次感谢您的帮助!!

@amaitland的评论有助于缩小这个问题的范围。

最新更新