首页 > 解决方案 > C# 在循环中显示另一个表单

问题描述

所以我正在尝试做一个程序,它会为每个呼叫的号码显示警报。我正在对我的路由器进行网络抓取,以获取被调用的号码。事情是;

while (true)
{
   Thread.Sleep(5000);
   if (!numbers.SequenceEqual(getNumber()))
   {
     numbers = getNumber();

     alert alert = new alert();
     alert.setAlert(numbers.First());
     //break;
   }
}

我正在使用一段时间,每 5 秒检查一次是否有人​​打电话。因此,当我显示警报(这只是另一种形式)时,它无法正确显示。我刚刚使用break进行了测试,它可以工作,所以我认为这是因为循环。我对异步方法知之甚少,我认为这可能是一个解决方案......?

感谢和抱歉我的英语不好!

更新整个代码;

表格1.显示


private void Form1_Shown(object sender, EventArgs e)
{
   ChromeDriverService service = ChromeDriverService.CreateDefaultService();
   service.HideCommandPromptWindow = true;

   ChromeOptions options = new ChromeOptions();
   options.AddArgument("headless");

   ChromeDriver driver = new ChromeDriver(service, options);
   driver.Navigate().GoToUrl("http://192.168.0.1/");

   var user = driver.FindElementByName("loginUsername");
   var pass = driver.FindElementByName("loginPassword");
   var submit = driver.FindElementByClassName("Login-button");

   user.SendKeys("blablabla");
   pass.SendKeys("blablabla");
   submit.Click();

   List<string> getNumber()
   {
        driver.Navigate().GoToUrl("http://192.168.0.1/CallLog.asp");

        var botonPerdidas = driver.FindElementByCssSelector("li[class='TabbedPanelsTab kR']");
        botonPerdidas.Click();

        List<string> strNumbers = new List<string>();
        for (int i = 2; i < 20; i++)
        {
          try
          {
             strNumbers.Add(driver.FindElementByXPath("/html/body/form/div/div[2]/div[2]/div/div[1]/div[1]/div/div[4]/div/div[" + i + "]/div[4]").Text);
          }
          catch (Exception)
          {
             break;
          }
        }
         return strNumbers;
   }


   List<string> numbers = getNumber();

   while (true)
   {
      Thread.Sleep(5000);
      if (!numbers.SequenceEqual(getNumber()))
      {
         numbers = getNumber();

         alert alert = new alert();
         alert.setAlert(numbers.First());
      }
   }

}

follow 方法在警报表单中,每次我检测到新呼叫时,都会从循环中的 form1 调用该方法。

警报.setAlert


public void setAlert(string msg)
{

    this.Text = msg;
    this.Opacity = 0.0;
    this.StartPosition = FormStartPosition.Manual;
    string fname;

    for (int i = 1; i <= 10; i++)
    {
       fname = "alert" + i.ToString();
       alert f = (alert)Application.OpenForms[fname];

       if (f == null)
       {
         this.Name = fname;
         this.x = Screen.PrimaryScreen.WorkingArea.Width - this.Width + 15;
         this.y = Screen.PrimaryScreen.WorkingArea.Height - this.Height * i - 5 * i;
         this.Location = new Point(this.x, this.y);
         break;
       }

    }

        this.x = Screen.PrimaryScreen.WorkingArea.Width - base.Width - 5;
        this.label1.Text = msg;
        this.Show();
}

试图将其从表单级别移出。

在此处输入图像描述

ErrorMessage:它在当前上下文中不存在。

标签: c#loopsasynchronousasync-await

解决方案


问题可能是由于 windows 窗体中的以下规则:

  1. 您不应使用长时间运行的操作阻塞 UI(主)线程
  2. 您只能从 UI 线程更新 ui 元素

在事件中运行无限循环Show()会破坏规则 #1 并会导致问题。

使您的驱动程序成为表单中的字段,并在构造函数中实例化 this(或在需要时显示事件)并创建一个执行 5 秒的常规计时器

ChromeDriverService service;
Timer myTimer;
public Form1(){
    InitializeComponent() 
    service = ChromeDriverService.CreateDefaultService();
    ...
    myTimer = new Timer();
    myTimer.Tick += TimerEventProcessor; 
    myTimer.Interval = 5000;
    myTimer.Start();
    ...
}

创建事件处理方法来处理事件:

private TimerEventProcessor(Object myObject, EventArgs myEventArgs) {
   
  if (!numbers.SequenceEqual(getNumber()))
  {
     numbers = getNumber();
     alert alert = new alert();
     alert.setAlert(numbers.First());
  }
}
    

推荐阅读