Остановка стороннего метода по таймеру c#

382
22 января 2017, 13:24

Есть метод сторонней библиотеки. Он обращается к серверу и либо получает данные и завершается, либо через 10 секунд автоматически закрывается. Завершение метода быстрее чем за 10 секунд не предусмотрено. Мне же надо его закрывать по истечении 100 миллисекунд работы. Хотелось бы сделать это без многопоточности. Есть идеи как это сделать?

Answer 1

Если исходников метода у вас нет — никак. Вы не можете остановить чужой код.

Правильная имплементация отмены задания — кооперативная: код, который вы хотите остановить, должен сотрудничать. Если вы прервёте его каким-то образом, то в лучшем случае вы оставите его структуры данных в неконсистентном состоянии, а в худшем — прервёте выполнение нативного кода в состоянии заблокированного heap lock'а.

Если библиотека не сотрудничает, не используйте её или потребуйте/попросите у авторов законную возможность управления отменой.

Вы, конечно, можете запустить сторонний метод в соседнем потоке, и по окончанию срока ожидания просто плюнуть на этот код и позволить ему дальше бежать, игнорируя результат. Это, понятно, далеко не самый лучший дизайн: вы блокируете поток надолго ради одной короткой операции.

Answer 2

Привожу

Намного удобнее составлять композиции асинхронных операций посредством Taskов. Поэтому, посмотрите, есть ли у api Вашей сторонней библиотеки поддержка Taskов?

Если да, то Ваш ответ в этих строчках

    static void Main(string[] args)
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        cts.CancelAfter(100);//отменяет задачу после указанного числа миллисекунд
        var res = TaskWrap(cts.Token);//функции с поддержками тасков обычно имеют перегрузку с CancellationToken
        Console.WriteLine(res.Result);
    }

Если же api сторонней библиотеки не поддерживает Taskи, то надо обернуть колбэк ответа в TaskCompletionSource и продолжить работу с таском

    static Task<string> TaskWrap(CancellationToken ct)
    {
        TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
        ct.Register(()=> {/* остановить загрузку, чтоб данные больше приходили, если это возможно*/ tcs.SetException(new TimeoutException()); });
        YourFunctionCallback(answer => tcs.SetResult(answer));
        return tcs.Task;
    }
READ ALSO
Обработка xml-файла linq и добавление его в DataGridView

Обработка xml-файла linq и добавление его в DataGridView

Необходимо обработать xml файл через Linq и добавить его в dgwFirstTable(DataGridView), например, добавить все записи, где YEAR>=1985Не могу сообразить как обращаться...

493
Пропадает текст из яйчейки в DataGridView

Пропадает текст из яйчейки в DataGridView

Собственно не могу понять почему происходит непонятное явление, при инициализации грида текст в ячейке появляется и сразу же исчезает

351
Расширяемая Windows служба

Расширяемая Windows служба

Хочу сделать расширяемую Windows службу, которая при своем запуске динамически загружает Dll

289
Как ответить на CURL запрос в формате xml в php?

Как ответить на CURL запрос в формате xml в php?

пожалуйста помогите сформировать серверный часть кода я делаю CURL запрос

465