我正在尝试使用我的cefSharp winform项目加载两个网页。第一页肯定会显示出来,因为它是一个本地的html页面。第二页需要ping,因为它是一个服务器网站。我需要先检查服务器IP和端口是否可以先连接,然后重定向到该页面。以下是我的编码:
public Form1()
{
Console.WriteLine("-------Initialization------");
InitializeComponent();
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(0, 0);
BrowserSettings browserSettings = new BrowserSettings();
Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory + "html\\index.html");
browser = new CefSharp.WinForms.ChromiumWebBrowser(AppDomain.CurrentDomain.BaseDirectory + "html\\index.html")
{// First page.
Dock = DockStyle.Fill,
};
this.Controls.Add(browser);
browser.BrowserSettings.WebSecurity = CefState.Disabled;
browser.BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
while (true)
{
pSvr = PingServer(ioIP, int.Parse(ioPort));
if (pSvr == true)
{
label3.Text = "Connected to server. Please wait...";
tmr.Interval = 15000;
tmr.Tick += timerHandler;
tmr.Start();
break;
}
Thread.Sleep(5000);
}
}
public bool PingServer(string _HostIP, int _PortNumber)
{
try
{
TcpClient client = new TcpClient(_HostIP, _PortNumber);
Console.WriteLine("Server successfully connected...");
return true;
}
catch
{
Console.WriteLine("Error pinging server...");
return false;
}
}
private void timerHandler(object sender, EventArgs e)
{
tmr.Stop();
browser.Load("http://" + ioIP + ":" + ioPort + "/page2/?1"); // second page
}
我使用while循环并执行thread.sleep 5秒钟,以便在失败时重试连接到服务器。
从逻辑上讲,无论我是否可以连接到第二页,我都希望首先显示第一页,然后在后台重试连接到第二页。但是当我运行我的代码时,当它无法连接到服务器时,第一页就不会出现了。好像它进入while循环并继续重试连接到第二页而忘记显示第一页。这是while循环问题吗?是否始终显示“错误ping服务器...”阻止显示第一页?那么你们认为它是最适合我重试连接服务器的方式?
答案 0 :(得分:0)
恕我直言,你不应该打扰“ping”。真正重要的是你是否可以加载页面。服务器完全无法访问只是其可能失败的众多可能原因之一,即使您成功“ping”服务器,您仍然可能在“ping”之后但在加载页面之前丢失连接,或者看到失败其他一些原因。你们认为它是最适合我重试连接服务器的方式吗?
不要试图检测服务器。只需加载页面并处理异常(如果发生)。
至于更大的问题,第一页没有出现,这是因为你在构造函数中做得太多了。构造函数在UI线程中执行,该线程负责对程序的可视外观进行所有更新。在从构造函数返回之前,该线程无法执行任何操作。因此,即使您已加载页面,控件也无法在屏幕上反映出来;你的构造函数正在捆绑线程。
基本解决方案是“不要那样做”。有很多方法可以避免这样做,但在这种情况下我觉得,因为你不应该首先“ping”服务器,你可以通过摆脱它来解决你的问题:
public Form1()
{
Console.WriteLine("-------Initialization------");
InitializeComponent();
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(0, 0);
BrowserSettings browserSettings = new BrowserSettings();
Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory + "html\\index.html");
browser = new CefSharp.WinForms.ChromiumWebBrowser(AppDomain.CurrentDomain.BaseDirectory + "html\\index.html")
{// First page.
Dock = DockStyle.Fill,
};
this.Controls.Add(browser);
browser.BrowserSettings.WebSecurity = CefState.Disabled;
browser.BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
tmr.Interval = 15000;
tmr.Tick += timerHandler;
tmr.Start();
}
这将立即加载第一页,等待15秒,然后尝试加载第二页。如果服务器在那里,它将显示。如果没有,你将得到一个未处理的例外;最好在try
/ catch
放置,并向用户提供一些有用的信息和选项(例如“无法连接,重试?”)。
如果你觉得你真的必须显示"Connected to server. Please wait..."
消息,即执行ping,那么你应该异步地这样做。例如:
protected override async void OnLoad(EventArgs e)
{
while (true)
{
pSvr = await PingServer(ioIP, int.Parse(ioPort));
if (pSvr == true)
{
label3.Text = "Connected to server. Please wait...";
tmr.Interval = 15000;
tmr.Tick += timerHandler;
tmr.Start();
break;
}
await Task.Delay(5000);
}
}
async Task<bool> PingServer(string _HostIP, int _PortNumber)
{
try
{
TcpClient client = new TcpClient();
await client.ConnectAsync(_HostIP, _PortNumber);
Console.WriteLine("Server successfully connected...");
return true;
}
catch
{
Console.WriteLine("Error pinging server...");
return false;
}
}
以上内容将完全替换构造函数中的循环(包括启动计时器...注意这意味着第二页将在加载第一页后不加载15秒,而是在成功检测到服务器后15秒加载)。