等待消息表单中的进度条 - 错误:InvalidOperationException跨线程操作无效 - C#

时间:2017-11-22 18:33:27

标签: c# winforms cross-thread

我可以使用以下方法在gridview(dgJEARequests)中显示自定义选项,如图所示。用户将选择将参数发送到查询whereStatement的项目。但是,当标记或选择了许多复选框(项目)时,将需要一些时间来加载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);
        }
    }

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

截图:

做我的选择

Selection

传递查询参数

Parameters

进度

ProgressBar

错误消息

Error

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

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

或者

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