Отменить задачи в c # [duplicate]

FilterIndex ... DefaultExt используется только во время сохранения. Индекс 1 основан, поэтому, если вы хотите выбрать второй oprion, тогда:

  dlg.FilterIndex = 2;   
49
задан Amir Karimi 5 December 2010 в 17:58
поделиться

6 ответов

  1. Не следует использовать Thread.Abort ()
  2. Задачи могут быть отменены, но не прерваны.

Метод Thread.Abort () (строго) устарел.

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

Если вам нужно запустить Process и убить его извне, единственным безопасным вариантом будет запуск его в отдельном AppDomain.

26
ответ дан Henk Holterman 17 August 2018 в 10:19
поделиться
  • 1
    @amkh - библиотека задач включает механизм отмены, называемый CancellationToken. Почему бы вам не использовать это? – Erik Funkenbusch 5 December 2010 в 18:09
  • 2
    @amkh: AppDomain выглядит правильно для вас. Вы не хотите, чтобы весь этот непредсказуемый код запускался в вашем основном пространстве памяти. – Henk Holterman 5 December 2010 в 18:39
  • 3
    Если вы вызываете сторонний компонент, который блокируется бесконечно (что, конечно же, не следует делать, но мы здесь встречаемся), вы не можете включить код, необходимый для опроса маркера отмены внутри этого компонента. И вам не нужно создавать отдельный исполняемый файл и AppDomain для любого кода или компонента, которые могут не возвращаться (или не возвращаться своевременно) из блокирующего вызова! – ALEXintlsos 17 May 2013 в 18:39
  • 4
    «... (строго) устарели. & quot; [нужна цитата] – Qwertie 6 February 2014 в 01:09
  • 5
    @Qwertie - это ссылка на Fx 3.5 и перед документацией . Немного трудно найти сейчас, он был очищен. Но заметьте сообщение внизу. В настоящее время обработка AbortException в основном исправлена ​​(наконец, блоки), но она по-прежнему не является полностью надежным подходом. – Henk Holterman 6 February 2014 в 01:20

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

На практике, если вы прервите поток, вы должны сделать это только вместе с убийством процесса. К сожалению, слишком много людей думают, что ThreadAbort - это жизнеспособный способ остановить что-то и продолжить, это не так.

Поскольку Tasks запускаются как потоки, вы можете вызывать ThreadAbort на них, но как и в случае с общими нитями, вы почти никогда хочу сделать это, кроме как в крайнем случае.

2
ответ дан Erik Funkenbusch 17 August 2018 в 10:19
поделиться
  • 1
    «не дал возможность очистить себя, оставив ресурсы восстановленными и вещи в неизвестных состояниях». & Quot; ... не совсем. Thread.Abort вызывает ThreadAbortException в потоке, в котором вы должны выполнять любые процедуры очистки. – Terry 17 January 2011 в 12:44
  • 2
    Вызов threadabort в управляемом потоке threadpool только когда-либо закончится в слезах ... Вызов threadabort в вашем собственном потоке, обеспечивающий обращение с ThreadAbortException, отлично. – Immortal Blue 28 December 2013 в 16:36

Если у вас есть конструктор задач, мы можем извлечь поток из задачи и вызвать thread.abort.

Thread th = null;

Task.Factory.StartNew(() =>
{
    th = Thread.CurrentThread;

    while (true)
    {
        Console.WriteLine(DateTime.UtcNow);
    }
});

Thread.Sleep(2000);
th.Abort();
Console.ReadKey();
-2
ответ дан Ivan Gusev 17 August 2018 в 10:19
поделиться
  • 1
    вы не должны вызывать Abort на потоках в пуле потоков – Jan-Fokke 27 July 2018 в 09:58

Но могу ли я прервать задачу (в .Net 4.0) таким же образом, а не механизмом отмены. Я хочу немедленно убить Задачу.

Другие ответчики сказали вам не делать этого. Но да, вы можете сделать это. Вы можете предоставить Thread.Abort() в качестве делегата, который будет вызван механизмом отмены задачи. Вот как вы могли бы настроить это:

class HardAborter
{
  public bool WasAborted { get; private set; }
  private CancellationTokenSource Canceller { get; set; }
  private Task<object> Worker { get; set; }

  public void Start(Func<object> DoFunc)
  {
    WasAborted = false;

    // start a task with a means to do a hard abort (unsafe!)
    Canceller = new CancellationTokenSource();

    Worker = Task.Factory.StartNew(() => 
      {
        try
        {
          // specify this thread's Abort() as the cancel delegate
          using (Canceller.Token.Register(Thread.CurrentThread.Abort))
          {
            return DoFunc();
          }
        }
        catch (ThreadAbortException)
        {
          WasAborted = true;
          return false;
        }
      }, Canceller.Token);
  }

  public void Abort()
  {
    Canceller.Cancel();
  }

}

отказ: не делайте этого.

Вот пример того, что не делать:

 var doNotDoThis = new HardAborter();

 // start a thread writing to the console
 doNotDoThis.Start(() =>
    {
       while (true)
       {
          Thread.Sleep(100);
          Console.Write(".");
       }
       return null;
    });


 // wait a second to see some output and show the WasAborted value as false
 Thread.Sleep(1000);
 Console.WriteLine("WasAborted: " + doNotDoThis.WasAborted);

 // wait another second, abort, and print the time
 Thread.Sleep(1000);
 doNotDoThis.Abort();
 Console.WriteLine("Abort triggered at " + DateTime.Now);

 // wait until the abort finishes and print the time
 while (!doNotDoThis.WasAborted) { Thread.CurrentThread.Join(0); }
 Console.WriteLine("WasAborted: " + doNotDoThis.WasAborted + " at " + DateTime.Now);

 Console.ReadKey();

output from sample code [/g1]

34
ответ дан jltrem 17 August 2018 в 10:19
поделиться
  • 1
    этот код не работает – DELUXEnized 21 February 2014 в 18:30
  • 2
    @DELUXEnized Это работает. Я добавил пример, чтобы использовать его. – jltrem 21 February 2014 в 19:23
  • 3
    Понимая Задачи, вы не должны смешивать функции Task и Thread. В одном потоке может быть много задач, вы прервите весь поток (со всеми его негативными последствиями), чтобы прервать одну задачу. Мне действительно нужно проголосовать за это. – Martin Meeser 13 October 2014 в 09:51
using System;
using System.Threading;
using System.Threading.Tasks;

...

var cts = new CancellationTokenSource();
var task = Task.Run(() => { while (true) { } });
Parallel.Invoke(() =>
{
    task.Wait(cts.Token);
}, () =>
{
    Thread.Sleep(1000);
    cts.Cancel();
});

Это простой фрагмент, чтобы прервать бесконечную задачу с помощью CancellationTokenSource .

-1
ответ дан Miles Naito 17 August 2018 в 10:19
поделиться
  • 1
    Это не отменяет задачу. Это просто перестает ждать завершения задачи. Он фактически продолжает работать, пока вызывающий абонент Task.Wait(...) возобновится со следующим утверждением. Вы можете легко проверить это, установив точку прерывания внутри цикла while. – Silvermind 18 July 2017 в 22:51
39
ответ дан Terry 17 August 2018 в 10:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: