Visual Studio 如何防止我的事件处理程序在用户界面线程上执行?

alen0pnh  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(95)

我有一个接收外部数据的Datagridview。
我的datagridview每10秒刷新一次,在刷新期间,表会 Flink (即,细胞收缩并恢复到其原始大小)。
经过一番研究,我发现问题在于我的事件处理程序运行在UI线程上,每次调用“Wait”时都会冻结该线程。我需要先获取所有需要的数据,然后启动一个线程或任务来完成这项工作。
你知道该怎么做吗?

private void dtgvPositions_DataBindingComplete(object sender, 
DataGridViewBindingCompleteEventArgs e)
{
    List<string> lstUID = this.ReplaceDownTheLine(this.txtUIDs.Text.Trim());
    Dictionary<string, bool> lstUIDColor = new Dictionary<string, bool>();
    for (int index = 0; index < lstUID.Count; ++index)
        lstUIDColor.Add(lstUID[index], index % 2 == 0);
    this.dtgvPositions.Invoke((Action)(() =>
    {
        foreach (string str in lstUID)
        {
            string uid = str;
            var nickNameTask = Task.Run<string>(async () => await this.GetTraderName(uid));
            nickNameTask.Wait();
            var nickName = nickNameTask.Result;

            foreach (DataGridViewRow row in (IEnumerable)this.dtgvPositions.Rows)
            {
                string key = row.Cells[1].Value.ToString();
                Decimal num = 0M;
                try
                {
                    num = Decimal.Parse(row.Cells[7].Value.ToString());
                }
                catch
                {
                }
                bool flag;
                lstUIDColor.TryGetValue(key, out flag);
                row.DefaultCellStyle.ForeColor = num >= 0M ? Color.Green : Color.Red;
                row.DefaultCellStyle.BackColor = flag ? FMain.COLOR_A : FMain.COLOR_B;
            }
        }
    }));
}
ttp71kqs

ttp71kqs1#

你可以简单地在另一个thread中这样做,但是记住,如果你想更新任何与控件相关的东西,使用Invoke

private void btnTest_Click(object sender, EventArgs e)
    {
        Task.Run(() =>
        {
            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(1000); // Assuming this is some action that takes time.
                this.Invoke(new Action(() => { 
                    // If there are operations related to controls, put them here.
                    txtLimit.Text = i.ToString();
                }));
            }
        });
    }

或者如果你的frameowrk支持,你可以使用jQuery和await。然后您可以直接操作您的控件。

private async void btnTest_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        await Task.Delay(1000); // Assuming this is some action that takes time.
        txtLimit.Text = i.ToString();
    }
}

相关问题