Progressbar in Waiting Message Form - Error: InvalidOperationException Cross-thread operation not valid - C#

Progressbar in Waiting Message Form - Error: InvalidOperationException Cross-thread operation not valid - C#

我有以下方法在 gridview (dgJEARequests) 中显示自定义的 selection 项,正如您从图像中看到的那样。用户将 select 将参数发送到查询 whereStatement 的项目。但是当许多复选框(项目)被标记或 selected 时,加载 dgJEARequests 中的所有数据将需要一些时间,比方说,5000 条记录或更少。所以,我决定添加一个WaitProcessing(一个带有进度条的表单)。当我单击搜索按钮 btnSearchSelection 时,出现此错误:

An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code

附加信息:跨线程操作无效:控件 'dgJEARequests' 从创建它的线程以外的线程访问

        private void ShowOnlyCustomSelection()
    {
        String whereStatement = "";
        List<String> fieldList = new List<String>();
        string getStatusName = "";
        string _getStatusName = "";

        //loop through all the checkboxes
        for (int i = 0; i < count; i++)
        {
            if (_cbStatus[i].Checked)
            {
                //getStatusName should give all selected options like this: 'New', 'Started', 'Accepted', etc., then pass it to whereStatement
                _getStatusName += ("'" + _cbStatus[i].Text + "'" + ",").TrimEnd();
            }
        }

        //trims the last comma (,)
        getStatusName = _getStatusName.TrimEnd(',');
        //textBox1.Text = _getStatusName.TrimEnd(','); //--->>this is for testing

        ////////////
        if (getStatusName == "" || getStatusName == null)
        {
            {
                MessageBox.Show("You have not selected your filter(s)!", "Filter Result", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
        else
        {
            //Build WHERE Statement
            fieldList.Add("RequestStatus.StatusName IN (" + getStatusName + ")");

            if (fieldList.Count > 0)
            {
                for (int x = 0; x < fieldList.Count; x++)
                {
                    if (x == 0)
                    {
                        whereStatement = fieldList[x];
                    }
                    else
                    {
                        whereStatement = whereStatement + " AND " + fieldList[x];
                    }
                }

                //Seach for Requests
                jeaRequests = itServices.getRequestsBySQLStatement(whereStatement);

                //dgJEARequests.DataSource = jeaRequests;
                requestList = new List<ITWebService.Requests>(jeaRequests.ToList());
                dgJEARequests.DataSource = requestList;
                dgJEARequests.ClearSelection();

                lblCountOfRequests.Text = requestList.Count.ToString().ToString() + " requests loaded";

            }
            else
            {
                if (chkMine.Checked)
                {
                    jeaRequests = itServices.getRequestsByAssignedToAndStatusID(JEAUser.UserName, "0");
                    //dgJEARequests.DataSource = jeaRequests;
                    requestList = new List<ITWebService.Requests>(jeaRequests.ToList());
                    dgJEARequests.DataSource = requestList;
                    dgJEARequests.ClearSelection();
                }
                else
                {
                    jeaRequests = itServices.getRequestsBySQLStatement("Requests.ID > 0");
                    //dgJEARequests.DataSource = jeaRequests;
                    requestList = new List<ITWebService.Requests>(jeaRequests.ToList());
                    dgJEARequests.DataSource = requestList;
                    dgJEARequests.ClearSelection();
                }
            }
        }
    }

这是 progressbar 的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JEAProjectManager
{
    public partial class WaitProcessing : Form
    {
        public Action Worker
        {
            get;
            set;
        }
        public WaitProcessing(Action worker)
        {
            InitializeComponent();

            if (worker == null)

                throw new ArgumentNullException();
            Worker = worker;

        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Task.Factory.StartNew(Worker).ContinueWith(t =>
            {
                this.Close();
            },
            TaskScheduler.FromCurrentSynchronizationContext());
        }
    }
}

另一个是当我点击搜索按钮时:

private void btnSearchSelection_CheckedChanged(object sender, EventArgs e)
    {
        //ShowOnlyCustomSelection();
        //WaitProcessing processing = new WaitProcessing();
        using (WaitProcessing processing = new WaitProcessing(ShowOnlyCustomSelection))
        {
            processing.ShowDialog(this);
        }
    }

查询参数被发送到 Web 服务。我该怎么做才能解决这个问题?我正在定制这个应用程序。我不是最初的开发者,但我的任务是让它变得更好。我知道那里有一些类似的错误,但情况不同。

截图:

做我的 selection

为查询传递参数

进度条

错误信息

可能重复:-/ How to deal with cross-thread access exceptions?

您需要确保访问线程已初始化

看起来答案很简单,但我花了一些时间才弄明白。我不确定是否有更好的解决方案,但我不得不将这些组件包含在 lambda 表达式中,例如:

lblCountOfRequests.Text = requestList.Count.ToString().ToString() + " requests loaded";

或者

dgJEARequests.Invoke(new Action(() => dgJEARequests.DataSource = requestList));