延迟计时器循环

时间:2018-07-28 17:49:19

标签: c# loops foreach

我在计时器中使用循环并尝试在其中添加延迟。但是它不起作用 而且我也不想使用Thread.sleep(),因为我的用户界面会冻结

我的代码:

private void Button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void Timer1_Tick(object sender, EventArgs e)
{
DoStuff();
}

private void DoStuff()
{
     foreach (ListViewItem item in ListView1.Items)
     {
        if(item.subitem[1].Text == 0)
          {
            MessageBox.Show("Hello")
            //Trying to add the delay here!!
          }

     }
}

我正在尝试使用private async void DoStuff() 并将await Task.Delay(milliseconds);添加到循环中。但是它不起作用,因为Timer1通过忽略延迟在每个刻度内调用DoStuff。(已测试)

测试代码(不起作用):

private void Button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void Timer1_Tick(object sender, EventArgs e)
{
DoStuff();
}

private async void DoStuff()
{
     foreach (ListViewItem item in ListView1.Items)
     {
        if(item.subitem[1].Text == 0)
          {
            MessageBox.Show("Hello")
            await Task.Delay(1000);
          }

     }
}

我的问题是我如何通过不将所有DoStuff Code移到计时器中来增加延迟(只需不更改代码位置来增加延迟)。

1 个答案:

答案 0 :(得分:1)

如我所写。您需要将方法定义为任务。该按钮代码具有一个称为DoStuff1的任务。这也意味着按钮必须定义为异步。 Bascailly,您的整个问题都是异步编程(谷歌认为-那里有很多很好的例子)。这样,您的用户界面就不会冻结。而且,您仍然可以在用户界面中使用其他按钮或文本。

public partial class Form1 : Form
{

    List<string> strings = new List<String>() { "Hello", "world", "!" };

    public Form1()
    {
        InitializeComponent();
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        string returnString = await DoStuff1();
    }

    private async Task<string> DoStuff1()
    {
        foreach (string s in strings)
        {
            MessageBox.Show(s);
            await Task.Yield();
            await Task.Delay(1000);
        }
        return "ASYNC DONE";
    }
}

[EDIT]喜欢吗?

public partial class Form1 : Form
{
    System.Timers.Timer t = new System.Timers.Timer(1000);

    List<string> strings = new List<String>() { "Hello", "world", "!" };

    public Form1()
    {
        InitializeComponent();
    }

    private async void button1_Click_1(object sender, EventArgs e)
    {
        System.Timers.Timer t = new System.Timers.Timer(1000);
        t.Elapsed += async (s, ev) => await DoStuff1();
        t.Start();
        //t.Stop(); //Stop immediately after and then you can add delays in DoStuff1() if you want to.
    }

    private async Task<string> DoStuff1()
    {
        foreach (string s in strings)
        {
            MessageBox.Show(s);
        }
        return "ASYNC DONE";
    }
}