从后台线程更新datagridview

时间:2016-12-19 00:40:29

标签: c# multithreading datagridview ping

我从UI调用Method,方法需要很长时间才能完成 所以它冻结了用户界面并阻止用户知道发生了什么。

我正在尝试更新' datagridview'的列(状态)在UI上反馈用户,让他知道哪个IP已连接,哪个尚未连接,但正如我在UI冻结之前说的那样,直到方法完成。

其中一个建议是使用线程,我这样做,但我的问题没有解决,所以我做了正确的事情?

    public void PatchUpdates()
    {
        try
        {
            foreach (DataGridViewRow OfficeListRow in DGV_OfficeList.Rows)
            {
                string OfficeIPAddress = OfficeListRow.Cells[3].Value.ToString();

                foreach (DataGridViewRow FileListRow in DGV_FileList.Rows)
                {
                    string SoruceFileNamePath = FileListRow.Cells[4].Value.ToString();
                    string DestinationFileNamePath = @"\\" + OfficeIPAddress + @"\usb1_1\test\" + Path.GetFileName(SoruceFileNamePath);

                    Thread foregroundthread = new Thread(() => CheckOffice(OfficeIPAddress));
                    foregroundthread.Start();

                    //check if connection to remote server is available
                    if (CheckOffice(OfficeIPAddress) == 1)
                    {
                        DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "Connected";
                        //file.copy(sorucefilenamepath, destinationfilenamepath, true); //copy files...
                    }
                    else if (CheckOffice(OfficeIPAddress) == 0)
                    {
                        DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "disconnected";
                    }
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

ping方法

    public int CheckOffice(string _ipAddress)
    {
        int timeout = 120;
        string data = "PingTestData";
        byte[] buffer = Encoding.ASCII.GetBytes(data);

        Ping PingSender = new Ping();
        PingOptions options = new PingOptions();

        options.DontFragment = true;

        PingReply reply = PingSender.Send(_ipAddress, timeout, buffer, options);

        if (reply.Status == IPStatus.Success)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }

1 个答案:

答案 0 :(得分:0)

目前您正在调用CheckOffice三次,一次在新线程中,两次在GUI线程中。不使用新线程中计算的返回值。

尝试更换:

                Thread foregroundthread = new Thread(() => CheckOffice(OfficeIPAddress));
                foregroundthread.Start();

                //check if connection to remote server is available
                if (CheckOffice(OfficeIPAddress) == 1)
                {
                    DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "Connected";
                    //file.copy(sorucefilenamepath, destinationfilenamepath, true); //copy files...
                }
                else if (CheckOffice(OfficeIPAddress) == 0)
                {
                    DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "disconnected";
                }

        var task = Task.Run(() =>
            {
                var result = CheckOffice(OfficeIPAddress);

                this.BeginInvoke((Action)(() =>
                {
                    if (result == 1)
                    {
                        DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "Connected";
                        //file.copy(sorucefilenamepath, destinationfilenamepath, true); //copy files...
                    }
                    else if (result == 0)
                    {
                        DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "disconnected";
                    }
                }));
            }
        );

这使用Task而不是显式Thread,如果你只是想启动异步逻辑,然后使用BeginInvoke使用GUI线程将更新应用到GUI,这是更好的做法,否则这将导致DataGridView出现问题控制不是线程安全的。应该在Winforms窗口或Control上定义BeginInvoke,或者您可以查看Dispatcher。