Шаблон для приостановки потоков, аналогичный шаблону CancellationTokenSource и CancellationToken?

#c# #design-patterns #cancellation #pausing-execution #cancellationtokensource

#c# #дизайн-шаблоны #отмена #приостановка-выполнение #cancellationtokensource

Вопрос:

Я начал использовать шаблон отмены совместного потока, предоставленный в framework 4.0 ConcellationTokenSource и CancellationToken, и я нашел его очень полезным и простым.

Теперь моя цель — предоставить моему приложению аналогичное элегантное и простое решение, но для приостановки потоков вместо их отмены. Поскольку и в этом случае запрос будет отличаться от прослушивания команды pause, я подумал, что было бы неплохо иметь что-то вроде PauseTokenSource и PauseToken. Итак, мой первый вопрос заключается в том, предлагаете ли вы такой шаблон для совместной приостановки или лучше что-то другое.

Если иметь такой шаблон — хорошая идея, есть ли у вас какие-либо предложения или рекомендации о том, как это сделать? На данный момент я думал, что источник должен иметь возможность приостанавливать и отменять приостановку с помощью ManualResetEvent и что токен должен иметь ссылку на источник. Это следует за первым черновиком, по которому, я надеюсь, вы сможете дать мне предложения по его улучшению.

 public class PauseTokenSource
{
    protected ManualResetEvent mre = new ManualResetEvent(true);
    object syncRoot = new object();

    public PauseToken PauseToken { get { return new PauseToken(this); } }

    public bool IsPauseRequested { get { return !mre.WaitOne(0); } }

    public void Pause()
    {
        mre.Reset();
    }

    public void UnPause()
    {
        mre.Set();
    }

    public void WaitUntillPaused()
    {
        mre.WaitOne();
    }
}

public class PauseToken
{
    private PauseTokenSource source;

    public PauseToken(PauseTokenSource source)
    {
        this.source = source;
    }

    public bool IsPauseRequested 
    { 
        get { return source != null amp;amp; source.IsPauseRequested; } 
    }

    public void WaitUntillPaused()
    {
        if (source != null)
            source.WaitUntillPaused();
    }
}
  

Комментарии:

1. Вы что-нибудь делали с этим или реализовали это где-нибудь?

2. Мне любопытно, для чего бы вы использовали эту «функцию»…

3. Вам не нужно, lock поскольку ManualResetEvent класс потокобезопасен.

Ответ №1:

Почему бы не создать интерфейс, который может реализовать PauseTokenSource, и не отправлять его вместо PauseTokens. Или в чем преимущество наличия экземпляров токенов, отличных от исходного? Я не вижу ни одного…

 public interface IPauseToken 
{
    bool IsPausedRequested { get; }
    void WaitUntillPaused();
}
  

И, кстати, WaitUntillPaused, разве это не должно быть WaitWhilePaused…