#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
цикла. Поместите aTimer
в свою форму и установите для ееInterval
свойства значение 5000. Поместите своеif
утверждение вTick
событие…3. Почему вы не можете сделать
driver
«глобальный» (переместить его на уровень формы)?4. Другими вариантами может быть использование
Aync
/Await
model .5. Правильно … вы бы ОБЪЯВИЛИ это на уровне формы, но оставили
new
часть вShown()
событии.
Ответ №1:
Проблема, вероятно, связана со следующими правилами в Windows forms:
- Вы не должны блокировать пользовательский (основной) поток длительными операциями
- Вы должны обновлять элементы пользовательского интерфейса только из потока пользовательского интерфейса
Выполнение бесконечного цикла в 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
нужно было удалить ее из формы, но теперь она работает отлично. Спасибо!