如何从线程设置ToolStripProgressBar的值?

时间:2012-04-24 20:45:39

标签: winforms multithreading c++-cli clr

现在,我知道当大多数人看到这种问题时,他们会想“噢使用代表”。好吧,使用委托。到目前为止,这是唯一拒绝与他们合作的控件。我也没有使用BackgroundWorker。

我自己写了一个System :: Threading :: Thread的包装类,因为我知道我将使用它们很多。我为类提供了各种委托事件,因此它可以与UI线程进行交互。我一直在使用它主要是为了设置状态栏的状态。我还有一个未使用的进度条,所以我想添加它。我给了它一个代表,但当我运行它时,它与臭名昭着的崩溃:

  

System.Windows.Forms.dll中出现未处理的“System.InvalidOperationException”类型异常

     

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

我现在很困惑,因为据我所知,我正在使用委托,就像我使用其他控件一样。这个特别吗?我已经远程搜索了互联网,我得到的只是C#BackgroundWorker问题,这些问题并不适用于此。这是我的代表的代码:

代表:

delegate void               OnThreadProgressUpdateDel(int progress, String^ status);

保存事件的变量:

OnThreadProgressUpdateDel^  m_updateProgressEvent;

事件的约束方式:

thread->OnThreadProgressUpdate += gcnew ObjectLoadThread::OnThreadProgressUpdateDel(this, &CObjectLoader::ProgressUpdate);

该事件名为:

void CObjectLoader::ProgressUpdate(int progress, String^ status)
{
    gGlobal->ProgramProgress->Maximum = 100;
    gGlobal->ProgramProgress->Value = progress; //Crash here...
    gGlobal->SetProgramStatus(status);
}

在这里打电话:

m_updateProgressEvent->Invoke(1, "Loading objects...");

这个愚蠢的ToolStripProgressBar让它不想更新有什么特别之处:(

在Microsoft Visual C ++ 2008 Express Edition中使用C ++ CLR,Windows窗体应用程序。

3 个答案:

答案 0 :(得分:2)

“ToolStripProgressBar没有Invoke方法。”

你是对的;但是toolStripProgressBar.ProgressBar.Invoke和InvokeRequired确实存在并按预期运行。

答案 1 :(得分:1)

Windows控件希望从创建它们的同一个线程进行修改。取决于控制和&操作,MDA或Exception不会触发,但它最好遵循标准:

if(InvokeRequired) control.Invoke();

每当处理线程和控件时都会出现

模式。

http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

答案 2 :(得分:0)

//使用以下代码Ahmad abbulkmailer.com

SetControlPropertyValue1(ProgressBar2,“value”,67);

委托void SetControlValueCallback1(ToolStripProgressBar oControl,string propName,object propValue);         private void SetControlPropertyValue1(ToolStripProgressBar oControl,string propName,object propValue){             if(oControl.GetCurrentParent()。InvokeRequired){                 SetControlValueCallback1 d = new SetControlValueCallback1(SetControlPropertyValue1);                 oControl.GetCurrentParent()。Invoke(d,new object [] {oControl,propName,propValue});             }             别的{

            Type t = oControl.GetType();
            PropertyInfo[] props = t.GetProperties();

            foreach (PropertyInfo p in props) {
                if (p.Name.ToUpper() == propName.ToUpper()) {
                    p.SetValue(oControl, propValue, null);
                }
            }
        }


    }