在后台每隔几秒运行一次功能,不会阻塞UI c#

时间:2016-09-21 13:22:46

标签: c# async-await task

如何使用task async await每隔几秒运行一次任务,而不会阻止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;
        }

2 个答案:

答案 0 :(得分:2)

看起来您正在使用System.Forms.Timer,它会在UI线程上引发其事件。因此,您希望将任何长时间阻塞的工作推送到后台线程:

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

答案 1 :(得分:-1)

首先需要将GetData定义为async方法,方法是更改​​返回类型:

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

还要与指南相匹配,您可能希望将async添加到方法名称

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

那么你可能希望通过Task.Factory.StartNew

覆盖GetDataAsync方法中的所有代码
Task<DataTable> GetData(){
  return Task.Factory.StartNew(() =>
  {
     ...
      return dt;
   });
}

修改 正如@MrinalKamboj所建议的那样 使用Task.Run Insted

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

        });

    return result;
}

重复任务你可能想要摆脱计时器并看看这个答案: RepeatActionEvery Method

希望有所帮助。