簡體   English   中英

無法對Windows窗體控件進行多線程安全調用

[英]cannot make multiple thread safe calls to windows forms control

我正在增強通過Web服務與SalesForce CRM交互的ac#win表單應用程序。

我有以下代碼來對表單上的標簽進行“線程安全”更新:

 delegate void SetTextCallback(string text);

 private void SetText(string text)
    {
        // InvokeRequired required compares the thread ID of the
        // calling thread to the thread ID of the creating thread.
        // If these threads are different, it returns true.
        if (this.lblAccessStatus.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.lblAccessStatus.Text = text;
            this.lblAccessStatus.Refresh();
        }
    }

我的表單(稱為SFDetachifier.cs )具有一個execute按鈕,該按鈕接受兩個日歷控件的日期,然后調用:

lblAccessStatus.Visible = true;
picProgress.Visible = true;

string fromDate = dtManualFromDate.Value.ToString("yyyy-MM-dd") + fromTime;
string toDate = dtManualToDate.Value.ToString("yyyy-MM-dd") + toTime;
string[] arg = new string[] { "S1", fromDate, toDate };
SFCtrl._SessionLog.Append("Manual detach requested on " + SFOrgName + "\n");
SFCtrl._SessionLog.Append("Date range requested: " + fromDate + " to " + toDate + "\n");

bgProcessing_Production.RunWorkerAsync(arg);

bgProcessing_Production具有用於后台工作程序的以下代碼,其中包括對setText的調用

private void bgProcessing_Production_DoWork(object sender, DoWorkEventArgs e)
    {
        String[] args = (String[])e.Argument;
        e.Result = args[0];

        // clear the datagrid view
        gvTaskCases.DataSource = null;
        //gvTaskCases.Rows.Clear();

        //if (gvTaskCases.Rows.Count != 0)
        //    {
        //    gvTaskCases.Rows.Clear(); // .Update();
        //    }

        SetText("login to SalesForce (on " + SFOrgName + ") ...please wait");

現在,當我運行我的應用程序時,我設置了一些日期,然后通過單擊“執行”按鈕執行上面的代碼,它可以正常工作(調用SalesForce XML Web服務)並將結果放入網格中。

一切正常,當我嘗試再次運行該過程時(例如,使用不同的日期)會出現問題

然后,我得到一個錯誤“跨線程操作無效:從其他線程(不是在其上創建的線程)訪問的控件”。

我不明白,我有一個代表設置嗎?

我在做什么錯-我猜測當backround worker再次運行時,它將在新線程上運行,因此是線程不安全的。

請問如何解決此錯誤?

您可以使用匿名委托將事情縮短一些,如下所示:

    private void removeGridDS()
    {
        this.gvTaskCases.Invoke((MethodInvoker)delegate
        {
            if (this.gvTaskCases.DataSource != null)
            {
                this.gvTaskCases.DataSource = null;
            }
        });
    }

    private void clear_gvTaskCases()
    {
        this.gvTaskCases.Invoke((MethodInvoker)delegate
        {
            if (this.gvTaskCases.Rows.Count != 0)
            {
                this.gvTaskCases.Rows.Clear();
            }
        });
    }

現在,您不需要硬編碼的委托。 此外,您沒有使用傳入的布爾值。

這是我為了解決此問題而最終要做的事情,正如上面的注釋之一所建議的,它似乎是對控件gvTaskCases的調用gvTaskCases了錯誤,因此我在該控件上創建了線程安全方法調用太:

delegate void SetTextCallback(string text);
delegate void clear_gvTaskCasesCallback(bool clearIt);
delegate void remove_gvTaskCasesDSCallback( bool removeDS);

private void removeGridDS(bool removeDS)
    {
        // InvokeRequired required compares the thread ID of the
        // calling thread to the thread ID of the creating thread.
        // If these threads are different, it returns true.
        if (this.gvTaskCases.InvokeRequired)
        {
        remove_gvTaskCasesDSCallback d = new remove_gvTaskCasesDSCallback(removeGridDS);
        this.Invoke(d, new object[] { removeDS });
        }
        else
        {
            if (this.gvTaskCases.DataSource !=null)
            {
            this.gvTaskCases.DataSource=null;
            }
        }
    }

    private void clear_gvTaskCases(bool clearIt)
    {
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.
    if (this.gvTaskCases.InvokeRequired)
    {
        clear_gvTaskCasesCallback d = new clear_gvTaskCasesCallback(clear_gvTaskCases);
        this.Invoke(d, new object[] { clearIt });
        }
        else
        {
        if (this.gvTaskCases.Rows.Count != 0)
        {
        this.gvTaskCases.Rows.Clear();
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM