Доброго времени суток всем читающим!
Помогите, пожалуйста, реализовать таймаут на C#.
Занимаюсь задачей автоматизации десктопного приложения с помощью фреймворка Winium.Cruciatus и требуется установить таймаут на поиск элемента приложения, то есть поиск элемента должен выполняться в пределах заданного времени и, в случае, если элемент за это время не будет найден должна формироваться ошибка, которую я потом смогу обработать.
Вот код поиска элемента, на который необходимо установить таймаут:
var OpenShift = CashierWindow.FindElementByname("Да");
{
try
{
OpenShift.Click();
CashierWindow.FindElementByUid("6").Click();
CashierWindow.FindElementByUid("6").Click();
}
catch
{
Console.WriteLine("...");
}
}
У Winium есть внутренний таймаут на поиск элемента.
Копать нужно в сторону Implicit и Explicit Waits и пробовать изменять их(предварительно почитав для чего каждый из них).
Т.к. они существуют УЖЕ (а они существуют, судя по https://github.com/2gis/Winium.Desktop/issues/227 ), то своя реализация своего отдельного таймаута будет ошибочным подходом.
Всем большое спасибо!
Большое спасибо! Натолкнули меня на идею реализации таймаута через запуск асинхронной операции.
Вот какая утилита получилась:
using System;
using System.Threading.Tasks;
using Winium.Cruciatus.Core;
using Winium.Cruciatus.Elements;
using Winium.Cruciatus;
static class IfExistsClass
{
public static CruciatusElement GetIfExists(By element, CruciatusElement root, double timeout = 90000)
{
var StartDateTime = DateTime.Now;
CruciatusFactory.Settings.SearchTimeout = (int)timeout;
while ((DateTime.Now - StartDateTime).TotalMilliseconds < timeout) ;
{
var FindElement = Task<CruciatusElement>.Run(() =>
{
var elementFound = root.FindElement(element);
return elementFound;
});
if (FindElement.Wait(TimeSpan.FromMilliseconds(30000)))
return FindElement.Result;
else
Console.WriteLine("Timeout поиска элемента");
}
return null;
}
}
Универсальный таймаут с использованием тасков:
public void TryFlush()
{
int FlushTimeOut = 11;
Task flushingTask = Task.Factory.StartNew(() => Flushing());
var timeoutMilliseconds = FlushTimeOut * 1000;
var isCompleted = flushingTask.Wait(timeoutMilliseconds);
if (!isCompleted)
throw new TimeoutException($"Время ожидания истекло(default {FlushTimeOut} seconds)");
Console.WriteLine("Flushed");
}
private void Flushing()
{
//ваша долгая задача
Thread.Sleep(10000);
Console.WriteLine("Flushing done");
}
static void Main(string[] args)
{
SetTimeout(2000, () => Console.WriteLine("2"));
Console.WriteLine("1");
Console.ReadKey();
}
static void SetTimeout(int delayMiliSeconds, Action action)
{
Task.Factory.StartNew(() =>
{
Thread.Sleep(delayMiliSeconds);
action.Invoke();
});
}
Еще setinterval
static void SetInterval(int delayMiliSeconds, Action action)
{
void Repeat()
{
var T = Task.Factory.StartNew(() =>
{
Thread.Sleep(delayMiliSeconds);
action.Invoke();
Repeat();
});
}
Repeat();
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть вот такой код для сравнения двух объектовПроблема в том, что if() с проверками на тип, имя и значение полей работает как-то неадекватно
Часы, минуты и секунды задаю с инспектораМне не нужен сверхточный таймер, но принцип правильный? А может есть какие-нибудь более легкие способы,...
подскажите как это реализовать:Персонаж должен тащить объектВ инете искал ничего не нашел
У меня имеется окно авторизации: TextBox для логина, PasswordBox для пароля и кнопочка - ВойтиПосле того как пользователь вводит данные мне нужно проверить...