C # Показывает другую форму в цикле

#c# #loops #asynchronous #async-await

#c# #циклы #асинхронный #асинхронное ожидание

Вопрос:

Итак, я пытаюсь создать программу, которая отображает предупреждение для каждого вызываемого номера. Я делаю webscraping для своего маршрутизатора, чтобы получить вызываемые числа. Дело в том,;

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

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

Я использую while, который постоянно каждые 5 секунд проверяет, звонил ли кто-то. И из-за этого, когда я показываю предупреждение (которое является просто другой формой), оно не отображается должным образом. Я только что выполнил тест с использованием break, и он работает, поэтому я предположил, что это из-за цикла. Я почти ничего не знаю об асинхронном методе, и я думаю, что это может быть решением …?

Спасибо и извините за мой плохой английский!

Обновление со всем кодом;

Form1.Показано


 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 в цикле каждый раз, когда я обнаруживаю новый вызов.

Alert.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();
}

  

Пытаюсь переместить ее с уровня формы.

введите описание изображения здесь

Сообщение об ошибке: оно не существует в текущем контексте.

Комментарии:

1. Выполняется ли этот цикл в основном потоке?

2. Избавьтесь от while цикла. Поместите a Timer в свою форму и установите для ее Interval свойства значение 5000. Поместите свое if утверждение в Tick событие…

3. Почему вы не можете сделать driver «глобальный» (переместить его на уровень формы)?

4. Другими вариантами может быть использование Aync / Await model .

5. Правильно … вы бы ОБЪЯВИЛИ это на уровне формы, но оставили new часть в Shown() событии.

Ответ №1:

Проблема, вероятно, связана со следующими правилами в Windows forms:

  1. Вы не должны блокировать пользовательский (основной) поток длительными операциями
  2. Вы должны обновлять элементы пользовательского интерфейса только из потока пользовательского интерфейса

Выполнение бесконечного цикла в Show() событии нарушает правило № 1 и вызовет проблемы.

Создайте в своем драйвере поле в форме, создайте экземпляр этого в конструкторе (или покажите событие, если необходимо) и создайте обычный таймер, который выполняется каждые 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());
  }
}
    
  

Комментарии:

1. Мне ChromeDriver нужно было удалить ее из формы, но теперь она работает отлично. Спасибо!