0

I am using a waiting task delay. I want to understand the problem by giving an example:

private async void timer2_Tick(object sender, EventArgs e)
    {
        await Task.Delay(5000);
        label1.Text = "1";
        await Task.Delay(5000);
        label1.Text = "2";
        await Task.Delay(5000);
    }

Timer internal: 1000 Problem : Always writes 1 and 2 to the label.Can not wait

When I write the above code to the timer, it always starts and nonsense. I want to sleep without freezing the form. how can I do that?

Appiah
  • 49
  • 1
  • 7
  • you should use `Task.Factory.StartNew` with ` Thread.Sleep();` in it. – Amogh Jun 02 '18 at 11:33
  • Also, as Timer interval is 1000 so you have to stop timer out of `Task.Factory.StartNew()` block – Amogh Jun 02 '18 at 11:53
  • could you give an example :) – Appiah Jun 02 '18 at 11:56
  • @Amogh, I agree that the timer must be stopped or have an interval bigger than 15000 but, in what `Task.Factory.StartNew` and `Thread.Sleep` would help here? – Paulo Morgado Jun 02 '18 at 18:21
  • @PauloMorgado A bit late to reply, but in `Task.Factory.StartNew` we can call `label1.Invoke()` to set text to label on UI thread. Anyways your answer is also perfect. – Amogh Jun 04 '18 at 04:41
  • In that case, you should be using `IProgress`\`Progress` instead of `Control.Invoke`. – Paulo Morgado Jun 04 '18 at 10:37

2 Answers2

1

Im not exactly sure why that would not work but there could be a number of reasons. You could be delaying the wrong thread/task(I'v ran into this issue in Java)? Could I ask if this code works inplace so we can get more information on the issue? If this works then it should confirm that the problem is a task or thread issue. You many need to modify this slightly and add breakpoints as needed.

        DateTime begin = DateTime.Now;
        DateTime firstDelay = begin.AddSeconds(5);
        DateTime secondDelay = begin.AddSeconds(10);
        DateTime thirdDelay = begin.AddSeconds(15);
        while (begin <= firstDelay)
        {
            begin = DateTime.Now;
        }
        label1.text = "1";
        while (begin <= secondDelay)
        {
            begin = DateTime.Now;                
        }
        label1.text = "2";
        while (begin <= thirdDelay)
        {
            begin = DateTime.Now;
        }
Zander
  • 84
  • 14
  • I could recommend looking into this page:https://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout the first comment on the best answer explains why task.delay is an issue – Zander Jun 02 '18 at 12:01
  • if(wait==0) { wait = 1; label1.Text = "1"; await Task.Delay(2000); label1.Text = "2"; await Task.Delay(2000); wait = 2; } if(wait==2) { wait = 0; } I did something like that but I need more stability :( – Appiah Jun 02 '18 at 12:10
  • You could also try the Thread.Sleep method : System.Threading.Thread.Sleep(5000); – Zander Jun 02 '18 at 12:16
  • the form need not be frozen. I just want to work like thread.sleep. However, the Await task always writes 1 and 2 to Label1. output: unfortunately unexpected series 1 and 2 :( why do not I understand why? :( – Appiah Jun 02 '18 at 12:23
1

What's the timer interval?

Try this:

private volatile int running;

private async void timer2_Tick(object sender, EventArgs e)
{
    if (this.running != 0)
    {
        return;
    }

    Interlocked.Exchange(ref this.running, 1);

    await Task.Delay(5000);
    label1.Text = "1";
    await Task.Delay(5000);
    label1.Text = "2";
    await Task.Delay(5000);

    Interlocked.Exchange(ref this.running, 0);
}
Paulo Morgado
  • 14,111
  • 3
  • 31
  • 59