2010-09-08 59 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语句是没用呢,因为它只会抓线程创建例外。)

相关问题