Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
v skopin
Member

Откуда: Germany
Сообщений: 895
Привет всем!

Собственно вопрос в сабже. вопрос возник от сюда
            var escape = new Thread(() =>
            {
                while (IsNotCancelled && !test.IsCompleted)
                {
                    if (ReadKey().Key == ConsoleKey.Escape)
                        _cancelSource.Cancel();
                    Write("\b");
                }
            });

Но вообще, стало просто интересно как это возможно...

Заранее благодарю

ЗЫ
escape.Abort() - не просто устарел в .NET 5, а ошибку генерирует

Сообщение было отредактировано: 25 май 21, 11:38
25 май 21, 11:45    [22326677]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
ЕвгенийВ
Member

Откуда: Москва
Сообщений: 4986
а еще можно на велеке тормозить засовывая ногу в спицы переднего колеса перед вилкой
25 май 21, 12:07    [22326689]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
fkfka
Member

Откуда:
Сообщений: 131
Ты что в итоге сделать-то хочешь? По коду у меня практически уверенность, что ты пытаешься забить гвоздь отверткой.
25 май 21, 12:33    [22326715]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
v skopin
Member

Откуда: Germany
Сообщений: 895
fkfka
Ты что в итоге сделать-то хочешь? По коду у меня практически уверенность, что ты пытаешься забить гвоздь отверткой.
Ecли пользователь не нажал, а другая задача завершилась(test.IsCompleted), то остановить ожидание ReadKey()
25 май 21, 12:43    [22326725]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
fkfka
Member

Откуда:
Сообщений: 131
v skopin,

using System;
using System.Threading;
using System.Threading.Tasks;

using CancellationTokenSource cancellationTokenSource = new();

Console.CancelKeyPress += (_, e) => {
    cancellationTokenSource.Cancel();
    e.Cancel = true;
};

try
{
    Console.WriteLine("Press Ctl-C to terminate.");
    await VeryLongTask(cancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
    Console.WriteLine();
    Console.WriteLine("Boo! Operation cancelled!");
}

async Task VeryLongTask(CancellationToken cancellationToken)
{
    Console.WriteLine("Starting a very long operation.");

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();
        Console.Write(".");
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
}


Идея понятна?
25 май 21, 13:29    [22326769]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
v skopin
Member

Откуда: Germany
Сообщений: 895
fkfka,
Спасибо)
-мой вар-нт сильно хуже)))

Но а всё таки(по теме), хочу грохнуть Task, как?
(допустим, закзчику не понравилось котрол-С)

или (не мой в-нт) зависло всё, а таймаута нет...

Сообщение было отредактировано: 26 май 21, 10:24
26 май 21, 10:30    [22327288]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
fkfka
Member

Откуда:
Сообщений: 131
v skopin
Но а всё таки(по теме), хочу грохнуть Task, как?

В случае ReadKey ответ - никак. Это операция, которая намертво блокирует поток и прервать ее можно только грохнув сам поток, что ныне уже невозможно.

Можно просто забить на этот поток - он сам грохнется при выходе. Например так:

using System;
using System.Threading;
using System.Threading.Tasks;

using CancellationTokenSource cancellationTokenSource = new();
Console.WriteLine("Press any key to terminate.");

// "Start" tasks
var readAnyKey = ReadAnyKey();
var longOperation = VeryLongTask(cancellationTokenSource.Token);

// Wait for any task to finish
var finished = await Task.WhenAny(readAnyKey, longOperation);

// A key's been pressed
if (finished == readAnyKey)
{
    // causes cancelling the other task
    cancellationTokenSource.Cancel();

    // just wait for another task to be cancelled
    try
    {
        await longOperation;
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine();
        Console.WriteLine("Boo! Operation cancelled!");
    }
}

// This task is completed as soon as any key is pressed
Task ReadAnyKey() => Task.Run(() => Console.ReadKey(true));

// Some long operation
async Task VeryLongTask(CancellationToken cancellationToken)
{
    Console.WriteLine("Starting a very long operation.");

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();
        Console.Write(".");
        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
    }
}
26 май 21, 12:33    [22327378]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4207
v skopin,

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

Сообщение было отредактировано: 26 май 21, 12:50
26 май 21, 12:58    [22327397]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
fkfka
Member

Откуда:
Сообщений: 131
Roman Mejtes
если ФС пойдет пойдет по детородному органу

С какого органа ФС пойдет по органу при убивании пользовательского процесса?
26 май 21, 13:02    [22327400]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
love_bach
Member

Откуда:
Сообщений: 822
v skopin
Привет всем!

Собственно вопрос в сабже. вопрос возник от сюда
            var escape = new Thread(() =>
            {
                while (IsNotCancelled && !test.IsCompleted)
                {
                    if (ReadKey().Key == ConsoleKey.Escape)
                        _cancelSource.Cancel();
                    Write("\b");
                }
            });

Но вообще, стало просто интересно как это возможно...

Заранее благодарю

ЗЫ
escape.Abort() - не просто устарел в .NET 5, а ошибку генерирует


нельзя
26 май 21, 21:53    [22327700]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
VSVLAD
Member

Откуда: Краснодар
Сообщений: 1398
v skopin,

как уже сказали и сам MS пишет, метод Abort не поддерживается. Рекомендует создавать отдельный процесс его грохать при необходимости. Правда придётся немного подумать как передать в запускаемый процесс параметры (межпроцессное взаимодействие наладить). Сам вот мучаться буду скоро, перенося проект на .NET 5.

Есть приложение-хост, которое компилирует пользовательский код с блекджеком и запускает на исполнение в таске. Но если пользователь ошибся и правильное не завершил метод или токен отмены не проверил, то хост может бесконечно долго тратить ресурс зря. Была кнопка прибить поток, теперь нет кнопки
26 май 21, 23:03    [22327731]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
fkfka
Member

Откуда:
Сообщений: 131
VSVLAD
Есть приложение-хост, которое компилирует пользовательский код с блекджеком и запускает на исполнение в таске. Но если пользователь ошибся и правильное не завершил метод или токен отмены не проверил, то хост может бесконечно долго тратить ресурс зря. Была кнопка прибить поток, теперь нет кнопки

Сама по себе задумка давать пользователю запускать на сервере свой произвольный код на приз года совсем не тянет.
26 май 21, 23:25    [22327733]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
VSVLAD
Member

Откуда: Краснодар
Сообщений: 1398
fkfka,

Увы, задачи такие приходят, что времни не напасешся под каждую делать опции в пользовательском интерфейсе. Сейчас продумываем другой подход, делать сценарий на более высоком уровне в виде блок-схем описанные в xml. Уже рабочий прототип есть в аналогичном решении, там можно почти полноценный Control Flow сделать и добавить свой блекджек
27 май 21, 08:06    [22327779]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
jenya7
Member

Откуда:
Сообщений: 1381
я обычно делаю так
private void ThreadRun()  
{
    while (run == true)
    {
        //do something
    }
}       

а если надо завершить
private void ButtonStop_Click(object sender, EventArgs e)
{
    run = false;
}

Мне кажется вполне себе решение.
27 май 21, 10:31    [22327828]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22390
jenya7
Мне кажется вполне себе решение.
да. В 90-х годах вполне себе нормальное ))
27 май 21, 10:33    [22327831]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
jenya7
Member

Откуда:
Сообщений: 1381
Shocker.Pro
jenya7
Мне кажется вполне себе решение.
да. В 90-х годах вполне себе нормальное ))

Процес при завершении выгрузиться не? Можно создать новый и не париться.
27 май 21, 10:54    [22327838]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4207
jenya7,

в 2021 году люди используют CancellationToken'ы, таски вместо Thread'ов и другие ништяки.
А это:
private void ThreadRun()  

{
    while (run == true)
    {
        //do something
    }
}


Сообщение было отредактировано: 27 май 21, 12:11
27 май 21, 12:19    [22327889]     Ответить | Цитировать Сообщить модератору
 Re: Всё таки можно как-то грохнуть Thread/Task без отмены?  [new]
v skopin
Member

Откуда: Germany
Сообщений: 895
Вообще, получился симпатичный простенький прогресс-бар
        private static void DisplayProgress(Task test, CancellationTokenSource cancellation, int frequency = 40)
        {
            void Escape(object _, ConsoleCancelEventArgs consoleCancelEventArgs)
            {
                Write("\b");
                WriteLine("Принудительная остановка [ЧЕГО-ЛИБО], подождите ...");
                cancellation.Cancel();
                consoleCancelEventArgs.Cancel = true;
            }

            CancelKeyPress += Escape;
            CursorVisible = false;

            try
            {
                while (!test.IsCompleted)
                {
                    Write("\\");
                    Thread.Sleep(frequency);
                    if (test.IsCompleted)
                    {
                        Write("\b");
                        break;
                    }

                    Write("\b|");
                    Thread.Sleep(frequency);
                    if (test.IsCompleted)
                    {
                        Write("\b");
                        break;
                    }

                    Write("\b/");
                    Thread.Sleep(frequency);
                    if (test.IsCompleted)
                    {
                        Write("\b");
                        break;
                    }

                    Write("\b—");
                    Thread.Sleep(frequency);
                    Write("\b");
                }
            }
            finally
            {
                CancelKeyPress -= Escape;
                CursorVisible = true;
                Write("\b");
            }
        }
может кому пригодится)

Сообщение было отредактировано: 27 май 21, 16:56
27 май 21, 17:02    [22328113]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить