每隔几秒在后台运行函数,而不会阻塞UI c#

本文关键字:UI 函数 运行 后台 几秒 | 更新日期: 2023-09-27 18:08:01

如何在不阻塞UI的情况下每隔几秒使用任务异步等待运行一个任务?下面是我使用计时器的示例。我能够每隔几秒钟运行一次函数,但它阻塞了UI。谁能帮帮我,我是异步编程新手。

 private void Form1_Load(object sender, EventArgs e)
        {
            gridControl1.DataSource = GetData();
            timer.Interval = 5000;
            timer.Tick += new EventHandler(MyTimer_Tick);
            timer.Start();
        }

        private void MyTimer_Tick(object sender, EventArgs e)
        {
           gridControl1.DataSource = GetData();
           gridControl1.RefreshDataSource();
        }
        DataTable GetData()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Value1", typeof(int));
            dt.Columns.Add("Value2", typeof(int));
            dt.Columns.Add("Value3", typeof(int));
            dt.Columns.Add("Value4", typeof(int));
            dt.Columns.Add("Value5", typeof(int));
            dt.Columns.Add("Value6", typeof(int));
            dt.Columns.Add("Value7", typeof(int));
            dt.Columns.Add("Value8", typeof(int));
            dt.Columns.Add("Value9", typeof(int));
            dt.Columns.Add("Value10", typeof(int));
            dt.Columns.Add("Value11", typeof(int));
            dt.Columns.Add("Value12", typeof(int));
            Random rnd = new Random();
            for (int i = 1; i < 1000000; i++)
            {
                dt.Rows.Add(rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100),
                    rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100),
                    rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100));
            }
            return dt;
        }

每隔几秒在后台运行函数,而不会阻塞UI c#

看起来您正在使用System.Forms.Timer,它在UI线程上引发其事件。所以,你会想把任何长时间阻塞的工作推到后台线程:

private async void MyTimer_Tick(object sender, EventArgs e)
{
 gridControl1.DataSource = await Task.Run(() => GetData());
 gridControl1.RefreshDataSource();
}

首先需要将GetData定义为异步方法,通过更改返回类型来实现:

Task<DataTable> GetData(){...}

也是为了匹配指南,你可能想在方法名

中添加async
Task<DataTable> GetDataAsync(){...}

那么你可能想要覆盖所有的代码在GetDataAsync方法的任务。工厂. startnew

Task<DataTable> GetData(){
  return Task.Factory.StartNew(() =>
  {
     ...
      return dt;
   });
}

编辑:@MrinalKamboj建议使用任务。本月运行

Task<DataTable> GetData(){
string result = await Task.Run(() =>
        {
            ...
           return dt;
        });
    return result;
}

重复的任务,你可能想要摆脱定时器,看看这个答案:RepeatActionEvery方法