多线程网格视图更新

本文关键字:更新 视图 网格 多线程 | 更新日期: 2023-09-27 18:36:55

在这里,我在C#中使用了简单的逻辑。我从两个DateTimePicker中减去天数,并生成与总天数相同的GridView行数。我把这个逻辑放在一个Timer中,它以 100 毫秒的间隔滴答并自动执行。这适用于 90-100 行,但如果它达到 1000 行,则程序会卡住。所以,我认为我需要使用线程。我该怎么做?我知道基本的多线程,并尝试了这个,但没有奏效:

private void timer1_Tick(object sender, EventArgs e)
{
    myMethod();
}
void myMethod() {
    ed_Picker.MinDate = sd_Picker.Value;
    TimeSpan ts = new TimeSpan();
    //GridView.Rows.cont
    label3.Text = ed_Picker.Value.CompareTo(sd_Picker.Value).ToString();
    //dateTimePicker2.MinDate = dateTimePicker1.Value;
    ts = ed_Picker.Value.Subtract(sd_Picker.Value);
    double d;
    d = Math.Ceiling(ts.TotalDays) + 1;
    label3.Text = d.ToString();
    DataGridViewRow row = new DataGridViewRow();

    GridView.RowCount = Int32.Parse(d.ToString()); // This is key line which I like to put in new Thread
    for (int i = 1; i <= GridView.RowCount; i++)
    {
        GridView.Rows[i - 1].Cells[0].Value = sd_Picker.Value.AddDays(Convert.ToDouble(i - 1)).ToLongDateString();
        GridView.Rows[i - 1].Cells[0].ReadOnly = true;
    }
    DateTimeConverter dtc = new DateTimeConverter();
    TimeSpan ts1 = new TimeSpan();
    try
    {
        for (int i = 0; i < GridView.RowCount; i++)
        {
            ts1 += Convert.ToDateTime(GridView.Rows[i].Cells[2].Value).Subtract(Convert.ToDateTime(GridView.Rows[i].Cells[1].Value));
        }
    }
    catch (Exception ex)
    {
    }
    label6.Text = ts1.ToString();
}

多线程网格视图更新

以下是如何使用 BackgroundWorker 执行线程工作和更新 UI 的一般思路:

var worker = new BackgroundWorker {WorkerReportsProgress = true};
worker.DoWork += this.ThreadWorkMethod;
worker.ProgressChanged += this.ThreadProgressMethod;
worker.RunWorkerAsync();
...
private void ThreadWorkMethod(object sender, DoWorkEventArgs e)
{
    var worker = (BackgroundWorker)sender;
    for (int i = 0; i = 1000; i++)
    {
        // Time consuming operation
        Thread.Sleep(1000);
        worker.ReportProgress(i * 100d / 1000, i);
    }
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // Here you can access controls, etc.
    if (e.Progresspercentage == 100)
    {
        this.progLabel.Text = "100% Done";
    }
    else
    {
        this.progLabel.Text = string.Format("{0}% ({1} / 1000)",
                                            e.ProgressPercentage,
                                            e.UserState);
    }
}

如果您也想收听RunWorkerCompleted事件 - 您还可以从那里访问控件等。

因此,DoWork 方法就是执行硬线程工作,并调用 ReportProgress,以便在需要时可以适当地更改 UI。RunWorkerCompleted 事件将在 DoWork 方法完成(返回或完成)时自动调用。