Как реализовать таймаут на C#?

130
20 августа 2019, 22:40

Доброго времени суток всем читающим!

Помогите, пожалуйста, реализовать таймаут на C#.

Занимаюсь задачей автоматизации десктопного приложения с помощью фреймворка Winium.Cruciatus и требуется установить таймаут на поиск элемента приложения, то есть поиск элемента должен выполняться в пределах заданного времени и, в случае, если элемент за это время не будет найден должна формироваться ошибка, которую я потом смогу обработать.

Вот код поиска элемента, на который необходимо установить таймаут:

var OpenShift = CashierWindow.FindElementByname("Да");
{
    try
    {
        OpenShift.Click();
        CashierWindow.FindElementByUid("6").Click();
        CashierWindow.FindElementByUid("6").Click();
    }
    catch
    {
        Console.WriteLine("...");
    }
}
Answer 1

У Winium есть внутренний таймаут на поиск элемента.

Копать нужно в сторону Implicit и Explicit Waits и пробовать изменять их(предварительно почитав для чего каждый из них).

Т.к. они существуют УЖЕ (а они существуют, судя по https://github.com/2gis/Winium.Desktop/issues/227 ), то своя реализация своего отдельного таймаута будет ошибочным подходом.

Answer 2

Всем большое спасибо!

Большое спасибо! Натолкнули меня на идею реализации таймаута через запуск асинхронной операции.

Вот какая утилита получилась:

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;
    }
}
Answer 3

Универсальный таймаут с использованием тасков:

    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"); 
    }
Answer 4
    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();
        }
READ ALSO
Не работает сравнение объектов по полям C#

Не работает сравнение объектов по полям C#

Есть вот такой код для сравнения двух объектовПроблема в том, что if() с проверками на тип, имя и значение полей работает как-то неадекватно

119
Правильно ли я сделал таймер?

Правильно ли я сделал таймер?

Часы, минуты и секунды задаю с инспектораМне не нужен сверхточный таймер, но принцип правильный? А может есть какие-нибудь более легкие способы,...

117
Персонаж должен тащить обьект [закрыт]

Персонаж должен тащить обьект [закрыт]

подскажите как это реализовать:Персонаж должен тащить объектВ инете искал ничего не нашел

117
MVVM Получить View в View Model

MVVM Получить View в View Model

У меня имеется окно авторизации: TextBox для логина, PasswordBox для пароля и кнопочка - ВойтиПосле того как пользователь вводит данные мне нужно проверить...

138