2010-09-08 29 views
2

我被困在上述問題中。我得到了很多解決方案,但都沒有爲我工作。 請找我特此代碼c# - 進度條[線程]跨線程操作無效:從其創建的線程以外的線程訪問控制'progressBar'

private void btnRunQuery_Click(object sender, EventArgs e) 
    { 
     try 
     { 

      Thread ProcessThread = new Thread(Process); 
      ProcessThread.Start(); 

      Thread.CurrentThread.Join(); 
     } 
     catch 
     { 
      Debug.WriteLine("Error in model creation"); 
      Console.WriteLine("Error in model creation"); 
     } 
     finally 
     { 
      //dsModel = null; 
     } 
    } 


private void Process() 
    { 

     using (var dataContext = new IControlerDataContext()) 
     { 
      dataContext.EnlistTransaction(); 

      IItemPropertyRepository itemPropertyRepository = ObjectContainer.Resolve<IItemPropertyRepository>(); 
      IList<ItemProperty> itemPropertyCollection = itemPropertyRepository.LoadAll(); 
      totalCount = itemPropertyCollection.Count; 
      currentCount = 0; 

      foreach (var itemProperty in itemPropertyCollection) 
      { 
       try 
       { 
        message = string.Empty; 
        currentCount++; 
        if (itemProperty.DeletedDate == null && (itemProperty.MetaItemProperty.ValueType == MetaItemPropertyValueType.MetaItemTableProperty || itemProperty.MetaItemProperty.ValueType == MetaItemPropertyValueType.MetaItemTableMultiSelectProperty)) 
        { 
         //Property refresh issue in only applicable for table and multitable property. 
         //Need to filter the itemproperty for Table and multitable select property. 
         message = ProcessItemProperty(itemProperty); 
         //txtLogDetails.Text += message + Environment.NewLine; 
         //txtLogDetails.Refresh(); 
         //txtLogDetails.ScrollToCaret(); 
        } 
        //Log(message); 
        //progressBar.Value = (Int32)(currentCount * 100/totalCount); 
        //progressBar.Refresh(); 
        Invoke(new MyDelegate(ShowProgressBar), (Int32)(currentCount * 100/totalCount)); 

       } 
       catch (Exception ex) 
       { 
        txtLogDetails.Text += "EXCEPTION ERROR : " + itemProperty.Id.ToString(); 
        dataContext.RollBackTransaction(); 
       } 
      } 
      dataContext.CompleteTransaction(); 
     } 
    } 

delegate void MyDelegate(int percentage); 
    private void ShowProgressBar(int percentage) 
    { 
     progressBar.Value = percentage; 
     progressBar.Refresh(); 
     //txtLogDetails.Text = message; 
    } 

當執行 「調用(新MyDelegate(ShowProgressBar)(Int32)已(CURRENTCOUNT * 100/TOTALCOUNT));」這條線它超出了範圍。它進入內部,永遠不會回來。也沒有發現異常。

任何人都可以請幫我從這裏?

感謝, 馬赫什

回答

4

控制progressBar必須從它創建的線程訪問。使用BeginInvoke

我會替換該行...

Invoke(new MyDelegate(ShowProgressBar), (Int32)(currentCount * 100/totalCount)); 

...通過這一個...

this.progressBar.BeginInvoke( 
    (MethodInvoker)delegate() { 
     this.progressBar.Value = 
      Convert.ToInt32(currentCount * 100/totalCount); }); 

或者可以替換這些行...

progressBar.Value = percentage; 
     progressBar.Refresh(); 
     //txtLogDetails.Text = message; 

...由那些行...

this.progressBar.BeginInvoke( 
    (MethodInvoker)delegate() { 
    progressBar.Value = percentage; 
    progressBar.Refresh(); 
    //txtLogDetails.Text = message; 

    }); 
+0

上面的代碼爲我的控制,我需要插入到「Process()」方法嗎? 否則,我需要插入該代碼? – Mahesh 2010-09-08 11:32:42

+0

我更新了我的答案以匹配您的代碼 – 2010-09-08 11:37:04

+0

嗨皮埃爾, 感謝您的快速回復 – Mahesh 2010-09-08 11:37:18

0

我認爲問題在於你用Thread.Join阻塞了UI線程。

Thread.Join理論上會繼續抽取UI消息,但事實上它並不總是有效。

請參閱Chris Brumme的博客here。特別是

實際效果是我們將總是泵COM通話等待進入您的STA。任何窗口的任何SendMessages都將被服務。但是大多數PostMessages會延遲,直到完成阻止。

你應該讓按鈕事件結束,並有新的線程後回來時,它完成的消息(例如,通過使用BackgroundWorker的或一些其他異步框架)

(你的catch語句是沒用呢,因爲它只會抓線程創建例外。)

相關問題