Таймер вызывается несколько раз

246
24 февраля 2018, 19:12

Игра викторина, задаем вопрос и проверяем ответ. Таймер вызывает событие подсказки. Время от времени, в беседах, когда отвечает много человек, таймер срабатывает два, а иногда и три раза, в итоге каждые 10 секунд отправляется 2-3 подсказки. Помогите исправить, думал как-то его залочить, но не знаю как.

//задаем вопрос
public void Question(string act)
    {
        //код
        //задаем вопрос
            SetTimer();
    }
    //Проверяем правельный ли ответ
    private void Procces(string useranswer, string answer)
    {
        if (useranswer != null)
        {
            if (useranswer == answer)
            {
                aTimer.Stop(); aTimer.Dispose();
                //код
                //говорим пользователю что ответ правильный, и задаем новый вопрос
                Question(Watcher.Username + " дал правильный ответ");
            }
            else if (useranswer.Contains("стоп"))
            {
                aTimer.Stop(); aTimer.Dispose();
            }
        }
    }
    //таймер
    private void SetTimer()
    {
     aTimer = new System.Timers.Timer(10000);
     aTimer.Elapsed += OnTimedEvent;
     aTimer.AutoReset = true;
     aTimer.Enabled = true;      
    }
Answer 1

Зачем вам тут таймер вообще? Гораздо проще без него. Вот пример:

Класс вопроса:

public class Question
{
    private string _questionText;
    private string _answer;
    private string _hint;
    private CancellationTokenSource cts = new CancellationTokenSource();
    public Question(string questionText, string answer, string hint)
    {
        _questionText = questionText;
        _answer = answer;
        _hint = hint;
    }
    public void Ask()
    {
        Console.WriteLine("Question is:");
        Console.WriteLine(_questionText);
        WaitAndHint();
        var ans = Console.ReadLine();
        while (ans != "exit" && ans != _answer)
        {
            Console.WriteLine("Wrooong - bong! Try anain!");
            ans = Console.ReadLine();
        }               
        if (ans == _answer)
            Console.WriteLine("Well done!");
        cts.Cancel();
    }
    private async void WaitAndHint()
    {
        if (!string.IsNullOrEmpty(_hint))
        {
            try
            {
                await Task.Delay(10000, cts.Token);
                Console.WriteLine(_hint);
            }
            catch (TaskCanceledException ex)
            {
                /* nope */
            }
        }
    }
}

Как использовать:

void Main()
{
    var questions = new[] {
        new Question("2+2=", "4", "hint: its start from 'fo' and ens with 'ur'"),
        new Question("Whats my name?", "Bot", "hint: Im a bot, what do you think?"),
    };
    foreach(var q in questions)
        q.Ask();
}

Вывод:

Question is:
2 + 2 =
hint: its start from 'fo' and ens with 'ur'
Well done!
Question is:
Whats my name?
hint: Im a bot, what do you think?
Well done!

UPD Если переписать функцию с хинтом, то можно показывать хинт постепенно

private async void WaitAndHint()
{
    int len = _hint.Length;
    int curr = 0;
    if (!string.IsNullOrEmpty(_hint))
    {
        try
        {
            do
            {                   
                await Task.Delay(1000, cts.Token);
                curr++;
                var stars = len - curr;
                var hit_out = _hint.Substring(0, curr) + new String('*', stars);
                Console.WriteLine(hit_out);
            } while (curr != len && !cts.Token.IsCancellationRequested);
        }
        catch (TaskCanceledException ex)
        {
            /* nope */
        }
    }
}

Вывод:

Question is:
2+2=
h******************************************
hi*****************************************
hin****************************************
hint***************************************
hint:**************************************
hint: *************************************
hint: i************************************
hint: it***********************************
hint: its**********************************
hint: its *********************************
hint: its s********************************
hint: its st*******************************
hint: its sta******************************
hint: its star*****************************
hint: its start****************************
hint: its start ***************************
hint: its start f**************************
hint: its start fr*************************
hint: its start fro************************
hint: its start from***********************
hint: its start from **********************
hint: its start from '*********************
hint: its start from 'f********************
hint: its start from 'fo*******************
hint: its start from 'fo'******************
hint: its start from 'fo' *****************
hint: its start from 'fo' a****************
hint: its start from 'fo' an***************
hint: its start from 'fo' and**************
hint: its start from 'fo' and *************
hint: its start from 'fo' and e************
hint: its start from 'fo' and en***********
hint: its start from 'fo' and ens**********
hint: its start from 'fo' and ens *********
hint: its start from 'fo' and ens w********
hint: its start from 'fo' and ens wi*******
hint: its start from 'fo' and ens wit******
hint: its start from 'fo' and ens with*****
hint: its start from 'fo' and ens with ****
hint: its start from 'fo' and ens with '***
hint: its start from 'fo' and ens with 'u**
hint: its start from 'fo' and ens with 'ur*
hint: its start from 'fo' and ens with 'ur'
Answer 2

Я, наверное, тот еще лол. Если я инициализирую таймер 1 раз

aTimer = new System.Timers.Timer(10000);

А сам код таймера тогда изменю на:

private void SetTimer()
    {
     aTimer.Start();
     aTimer.Elapsed += OnTimedEvent;
     aTimer.AutoReset = true;
     aTimer.Enabled = true;      
    }

По идее, он уже не будет вызывать событие больше одного раза?

READ ALSO
Как открыть Form2 из Form1(усложнённо, не паста )

Как открыть Form2 из Form1(усложнённо, не паста )

Понадобилось мне вызвать с одной формы другую, но в чём загвоздка, если я пишу:

211
Как авторизоваться на сайте и получить код html страницы C# [требует правки]

Как авторизоваться на сайте и получить код html страницы C# [требует правки]

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

187
Шифрование файла в ресурсах

Шифрование файла в ресурсах

Подскажите есть ли какие-нибудь методы шифрования позволяющие зашифровать исходный код (txt,exe) файла в ресурсах?

180
C# Графика(прямая линия и круг)

C# Графика(прямая линия и круг)

Можно ли в консоли нарисовать прямую линию и круг?(не в форме, где нужно добавлять специальный блок, где можно рисовать) Если да, тогда хотелось...

469