0

我有方法更新UI使用並行任務

public override void InitializeRow(object sender, InitializeRowEventArgs e) 
    { 
     if (!e.ReInitialize) 
     Task.Factory.StartNew(() => 
      { 
       AfterInitializeRow(sender, e); 
      }); 
    } 

    public override void AfterInitializeRow(object sender, InitializeRowEventArgs e) 
    {    
      foreach (UltraGridColumn ugc in e.Row.Band.Columns) 
      { 
       if (IsNumeric(ugc.Key)) 
       { 
        e.Row.Cells[ugc].DroppedDown = true; 
        e.Row.Cells[ugc].ValueList = 「Some value」; 
        e.Row.Cells[ugc].SetValue(e.Row.Cells[ugc.Key].Value, false); 
        e.Row.Cells[ugc].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.DropDownList;       
       } 
      } 
    } 

但其在e.Row.Cells給錯誤[UGC] .DroppedDown = TRUE; 我瞭解到只有主線程才能更新UI。 但是有可能在更新DroppedDown時只切換到主線程。超過1000行的Bcoz以這種方式初始化,使網格的負載非常緩慢。所以我想在這個過程中做一些並行處理。

+0

如果修復了'e.Row.Cells [ugc] .DroppedDown = true;'行中的錯誤,您將在下一行出現異常等等。接受你無法從另一個線程更新UI的現實。如果你設法這樣做了,一些不好的事情正在等着你。 – 2014-11-06 12:13:22

+2

如果你使用MVVM,你不會有這個問題。我擔心你的方法,你應該使用Dispatcher.Invoke。 – 2014-11-06 12:14:27

+0

@IL_Agent實際上是一個Windows應用程序,但使用4.5版本的.net。實際上,這部分代碼運行時間很長,我正在尋找一種更快的方法來完成這項任務。感謝您回覆 – Nijith 2014-11-06 13:28:18

回答

0

在任何功能在您的FormUserControl,您可以使用以下類型的代碼:

public void SetText(string text) 
{ 
    if (InvokeRequired) 
    { 
     BeginInvoke(new Action<string>(SetText), text); 
    } 
    else 
    { 
     label1.Text = text; 
    } 
} 

label1會在這種情況下,更新控制。
這將確保您調用UI線程上的函數。
儘管如此,您仍應該小心同步處理,但只需從另一個線程更新UI即可輕鬆完成。

0

這個問題的答案是,您不應該在InitialzieRow事件中使用線程來設置甚至訪問網格或其相關對象上的屬性。

你應該做的,是尋找方法來優化你在這個方法中首先要做的。例如,爲什麼將單元格的值設置爲其已有的值,應該可以刪除這行代碼而不會影響行爲。

此外,所有提供的邏輯僅基於列鍵,因此如果列具有一致的一組值,則可以在InitializeLayout中設置ValueList on the column而不是使用InitializeRow。