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。