2009-07-14 47 views
0

所以我想确保我的应用程序的UI线程上没有发生我所有的数据库/网络操作。为此,我通常使用BeginInvoke函数进行调用,然后使用Invoke执行实际更新。我不确定我是否正确地做了与应该做的事情相比的事情。任何人都可以请提供以下代码注释:C#中的异步加载 - 优化/正确使用?

private void folderTree_NodeExpandedChanged(object sender, RadTreeViewEventArgs e) 
    { 
     if (e.Node.Tag != null) 
     { 
      var path = (string) e.Node.Tag; 

      if (!string.IsNullOrEmpty(path)) 
      { 
       if (Directory.Exists(path)) 
       { 
        folderTree.BeginUpdate(); 

        BeginInvoke(
         new Action(() => GetDirectories(path, e.Node))); 

        folderTree.EndUpdate(); 
       } 
      } 
     } 
    } 

    private void GetDirectories(string path, RadTreeNode parent) 
    { 
     var dirs = (new DirectoryInfo(path)).GetDirectories(); 

     Array.ForEach(dirs, d => Invoke(new Action(
              () => AddNode(d.Name, d.FullName, parent)))); 
    } 
+0

感谢球员,我以为BeginInvoke做了一个非UI线程的异步调用。我使用了后台工作者,而且工作。 但是,一个简单的问题是,来自背景工作的事件worker_RunWorkerCompleted会在UI线程上触发,还是必须从它调用Invoke来更新UI组件? – 2009-07-14 20:12:53

回答

3

上的控件/形式,BeginInvoke工作推到UI线程,通过消息泵(与支付的特权小的开销)。所以你已经从UI线程去UI线程...我怀疑你想在这里的/ThreadPool或类似的地方...(也许ThreadPool将是最容易从当前位置)。

另外;你可能不想同步更新工作,并且你不需要在线程之间进行大量的切换;我会通过整个阵列(或中等大小的块);不是个人记录。

0

据我所知道的,下面的调用:

BeginInvoke(new Action(() => GetDirectories(path, e.Node))); 

...是非常小的不同,这一个:

GetDirectories(path, e.Node); 

它只是增加了额外的一层或两层的周围打电话,但那里没有异步性;这一切都发生在同一个线程上。您需要包含一些机制以将工作推送到另一个线程(BackgroundWorker控制,使用ThreadPool或类似的东西)

0

我会这样做。还没有尝试过这个代码,但它应该工作。

 public class ParameterInfo 
     { 
      string _path; 
      RadTreeNode _parent; 
     }   

    if (!ThreadPool.QueueUserWorkItem(new WaitCallback(GetDirectories), 
           new ParameterInfo 
           { 
             _path = path, 
             _parent = e.Node 
           })) 
     { 
      //should log, if a thread has not been created 
     } 

     private void GetDirectories(ParameterInfo param) 
     { 
       var dirs = (new DirectoryInfo(param._path)).GetDirectories(); 

       Array.ForEach(dirs, d => BeginInvoke(new Action( 
          () => AddNode(d.Name, d.FullName, param._parent)) 
          )); 
     }