[英]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.