[英]Part of code doesn't execute without delay
我的应用程序检测到IP是否更改。 如果ip与以前的IP不同,则将新的ip保存到文件中。 似乎很容易。
延时功能:
public void MyDelay(int milliseconds)
{
Stopwatch stopwatch = Stopwatch.StartNew();
while (stopwatch.ElapsedMilliseconds <= (long)milliseconds)
{
Application.DoEvents();
}
}
按钮点击事件:
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.BackColor = Color.Green;
while (true)
{
while (true) //force obtain new_ip
{
try
{
new_ip = new System.Net.WebClient().DownloadString("https://api.ipify.org");
}
catch
{
MyDelay(1000);
continue;
}
break;
}
if (old_ip != new_ip)
{
pictureBox1.BackColor = Color.Red;
File.AppendAllText(@"C:\users\pc\Desktop\ip.txt", new_ip + "\r\n");
old_ip = new_ip;
MessageBox.Show("New ip saved");
}
pictureBox1.BackColor = Color.Green;
}
}
关键是,如果我将这样的代码保留为这一部分: pictureBox1.BackColor = Color.Green;
将不会执行。
我必须对此进行更改:
pictureBox1.BackColor = Color.Green;
对此:
pictureBox1.BackColor = Color.Green;
MyDelay(1);
现在,Picturebox的颜色正在改变。 为什么那延迟修复? 如果我将MessageBox插入Picturebox,甚至不存在问题。 如果没有MyDelay,它也可以作为一种魅力。 那有什么意义呢?
另一个问题:应该每1秒检查一次ip。 那么,为什么更改IP时我必须等待5秒钟才能进行更改检测? 连接出现后,它应该在1秒钟后保存新的IP,但是大约需要5秒钟才能识别更改
您正在主线程中完成所有工作。 UI也在主线程中被更新。 这意味着您不允许用户界面以任何方式进行更新。
当您调用延迟函数时,它会调用Application.DoEvents()
,以使UI自行更新。
您应该重构代码以使用计时器,异步方法或后台工作线程,以便UI可以保持响应状态。
您绝对不要在按钮单击中创建无休止的while (true)
,这会阻止gui进行更新。 这就是为什么您的PictureBox
不会重新绘制(但是代码已执行)的原因。 如果您在那里睡觉(包含Application.DoEvents()
) ,则会处理绘制消息,并重新绘制PictureBox
。 但是,GUI线程仍然被阻止。
这种方式使用Application.DoEvents()
是不好的做法 ,因为在此还会处理其他按钮/窗体关闭,这会使您的应用程序非常不稳定。 因此,摆脱Application.DoEvents()。
请改用Timer
检查该站点的外部IP!
类似于: PSEUDO
public class Form1: Form
{
private Timer _timer;
public Form1()
{
InitializeComponent();
_timer = new Timer(.....);
_timer.Tick += Timer_Tick;
// etc!!!
}
}
private void Timer_Tick(object sender, EventArgs e)
{
string new_ip;
try
{
new_ip = new System.Net.WebClient().DownloadString("https://api.ipify.org");
}
catch
{
return;
}
if (old_ip != new_ip)
{
pictureBox1.BackColor = Color.Red;
File.AppendAllText(@"C:\users\pc\Desktop\ip.txt", new_ip + "\r\n");
old_ip = new_ip;
MessageBox.Show("New ip saved");
}
else
pictureBox1.BackColor = Color.Green;
}
在一个已删除的.net内部无法更新接口时,可以使用Application.DoEvents()
解决此问题。 也许这个问题可以进一步帮助。
如果我正确理解了您的意图,则可以尝试异步等待(不知道为什么它需要一个while循环,然后尝试catch以获取url的结果):
private async void button1_Click(object sender, EventArgs e)
{
pictureBox1.BackColor = Color.Green;
var newIp = await GetIpAsync();
if (oldIp != newIp)
pictureBox1.BackColor = Color.Red;
}
private async Task<string> GetIpAsync()
{
using (var httpClient = new HttpClient())
{
return await httpClient.GetStringAsync(@"https://api.ipify.org");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.