2011-12-22 89 views
0

我制作了一个应用程序,用于从给定的SharePoint站点下载文件夹,但其消耗内存高于60万K,一旦我点击连接按钮,任何人都可以给出改进我的代码的建议?Windows窗体内存占用过多应用程序

我试图调试我的表单和问题是在方法“私人无效MapWebs(SPWebCollection webList,TreeNode webparentNode)”,其中调用自己一遍又一遍地通过每个单一的网络及其子网,但我检查开始时,我点击连接,并经过代码行

using (SPSite CurrentSite = new SPSite(tbSite.Text)) 

内存使用量20,000ķ去到40000 K(约)

为了运行这个程序,你必须在尤尔安装SharePoint PC,这种类型的应用程序的一个例子是在这个链接,

enter link description here

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using Microsoft.SharePoint; 
using System.IO; 

namespace WindowsFormsApplication3 
{ 
    public partial class MainWindow : Form 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    //Connects to Sharepoint site provided and populates Webs and Subwebs and subwebs.... 
    private void bConnect_Click(object sender, EventArgs e) 
    { 
      //Getting current site 
      using (SPSite CurrentSite = new SPSite(tbSite.Text)) 
      { 
       //Opening TopLevel Web for Site given 
       using (SPWeb TopLevelWeb = CurrentSite.OpenWeb()) 
       { 
        //Clearing all the nodes in TreeWeb 
        TreeWeb.Nodes.Clear(); 
        //Creating a root (First Node for webtree) which will be Top Level web's title 
        TreeNode rootWebNode = new TreeNode(TopLevelWeb.Title); 
        //Giving node a tag, which will be used later on in order to get value of node 
        rootWebNode.Tag = TopLevelWeb; 
        //Check if Top Level Web got any Sub webs if it does, it will create a new node for them 
        //Calls Map Webs to check for more sub webs + mapping them on webtree as nodes 
        foreach (SPWeb CurrentWeb in TopLevelWeb.Webs) 
        { 
         try 
         { 
          TreeNode webNode = new TreeNode(CurrentWeb.Title); 
          webNode.Tag = CurrentWeb; 
          MapWebs(CurrentWeb.Webs, webNode); 
          TreeWeb.Nodes.Add(webNode); 
         } 
         finally 
         { 
          if (CurrentWeb != null) 
           CurrentWeb.Dispose(); 
         } 
        } 
       } 
      } 
     } 

    // Maps Webs and there sub webs on webtree 
    private void MapWebs(SPWebCollection webList, TreeNode webparentNode) 
    { 
      for (var i = 0; i < webList.Count; i++) 
      { 
       TreeNode node = new TreeNode(webList[i].Name); 

       using (SPWeb web = webList[i]) 
       { 
       node.Tag = webList[i]; 
        webparentNode.Nodes.Add(node); 
        if (webList[i].Webs.Count > 0) 
         MapWebs(webList[i].Webs, node); 
       } 
      } 
      GC.Collect(); 
    } 

    //when the form loads it clears the list and create new cloumns to be used 
    private void MainWindow_Load(object sender, EventArgs e) 
    { 
     bFolder.Enabled = false; 
     bConnect.Enabled = false; 
     lvFiles.GridLines = true; 
     lvFiles.View = View.Details; 
     lvFiles.Columns.Add("Name", lvFiles.Width/4, HorizontalAlignment.Left); 
     lvFiles.Columns.Add("Date Created", lvFiles.Width/3, HorizontalAlignment.Left); 
     lvFiles.Columns.Add("Size", lvFiles.Width/5, HorizontalAlignment.Left); 
     lvFiles.Columns.Add("Time Last Modified", lvFiles.Width/5, HorizontalAlignment.Left); 
     if (lvFiles.View == View.Details && lvFiles.Columns.Count > 0) 
      this.Width = lvFiles.Columns.Count * (lvFiles.Width/2); 
     lvFiles.Columns[lvFiles.Columns.Count - 1].Width = -2; 
    } 

    //creates directory for downloading folder 
    private bool CreateDirectoryStructure(string baseFolder, string filepath) 
    { 
     if (!Directory.Exists(baseFolder)) return false; 

     var paths = filepath.Split('/'); 

     for (var i = 0; i < paths.Length - 1; i++) 
     { 
      baseFolder = System.IO.Path.Combine(baseFolder, paths[i]); 
      Directory.CreateDirectory(baseFolder); 
     } 
     return true; 
    } 

    //opens an dialog box for selecting path where selected folder will be downloaded 
    private void bBrowse_Click(object sender, EventArgs e) 
    { 
     if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) 
     { 
      this.tbDirectory.Text = folderBrowserDialog1.SelectedPath; 
     } 
    } 

    //when a node is selected in webtree it checks for folders in it , + sub folders + folders...... 
    private void TreeWeb_AfterSelect(object sender, TreeViewEventArgs e) 
    { 
     TreeFolder.Nodes.Clear(); 
     TreeNode currentNode = TreeWeb.SelectedNode; 
     using (SPWeb oWeb = (SPWeb)currentNode.Tag) 
     { 
      foreach (SPList list in oWeb.Lists) 
      { 
       if (list is SPDocumentLibrary && !list.Hidden) 
       { 
        TreeNode folderNode = new TreeNode(list.Title); 
        folderNode.Text = string.Format("{0} ({1})", list.Title, list.ItemCount); 
        folderNode.Tag = list.RootFolder; 

        foreach (SPListItem listItem in list.Folders) 
        { 
         if (listItem.Folder != null) 
         { 
          TreeNode node = new TreeNode(listItem.Folder.Name); 
          node.Tag = listItem.Folder; 
          node.Text = string.Format("{0} ({1})", listItem.Folder.Name, 
               GetFilesCount(listItem.Folder)); 

          MapFolders(listItem.Folder.SubFolders, node); 
          folderNode.Nodes.Add(node); 
         } 
        } 

        TreeFolder.Nodes.Add(folderNode); 
       } 
      } 
     } 
    } 

    //Maps folder on foldertree 
    private void MapFolders(SPFolderCollection folderList, TreeNode parentNode) 
    { 
     for (var i = 0; i < folderList.Count; i++) 
     { 
       TreeNode node = new TreeNode(folderList[i].Name); 
       node.Text = string.Format("{0} ({1})", folderList[i].Name, 
              GetFilesCount(folderList[i])); 
       node.Tag = folderList[i]; 
       parentNode.Nodes.Add(node); 

       if (folderList[i].SubFolders.Count > 0) 
        MapFolders(folderList[i].SubFolders, node); 
     } 
    } 

    //Maps files in a folder to listview 
    private void TreeFolder_AfterSelect(object sender, TreeViewEventArgs e) 
    { 
     lvFiles.Items.Clear(); 
     TreeNode currentNode = TreeFolder.SelectedNode; 
     //if (currentNode != rotnode) 
     //{ 
     double TotalSize = 0; 
     SPFolder oFolder = (SPFolder)currentNode.Tag; 
     foreach (SPFile oFile in oFolder.Files) 
      { 
       TotalSize += (oFile.Length)/1024/1024; 

       ListViewItem LTI = new ListViewItem(oFile.Name.ToString()); 
       LTI.SubItems.Add(oFile.TimeCreated.ToString()); 
       LTI.SubItems.Add(oFile.Length.ToString()); 
       LTI.SubItems.Add(oFile.TimeLastModified.ToString()); 
       lvFiles.Items.Add(LTI); 
      } 
      label4.Text = TotalSize.ToString(); 
     //} 
    } 

    //download selected folder + validation 
    private void bFolder_Click(object sender, EventArgs e) 
    { 
      TreeNode currentNode = TreeFolder.SelectedNode; 
       SPFolder oFolder = (SPFolder)currentNode.Tag; 
       foreach (SPFile file in oFolder.Files) 
       { 
        if (CreateDirectoryStructure(tbDirectory.Text, file.Url)) 
        { 
         var filepath = System.IO.Path.Combine(tbDirectory.Text, file.Url); 
         byte[] binFile = file.OpenBinary(); 
         System.IO.FileStream fstream = System.IO.File.Create(filepath); 
         fstream.Write(binFile, 0, binFile.Length); 
         fstream.Close(); 
        } 
       } 
    } 

    //calculates files in selected folder 
    private int GetFilesCount(SPFolder folder) 
    { 
     int fileCount = folder.Files.Count; 
     foreach (SPFolder subfolder in folder.SubFolders) 
     { 
      fileCount += GetFilesCount(subfolder); 
     } 
     return fileCount; 
    } 

    //validation 
    private void tbSite_TextChanged(object sender, EventArgs e) 
    { 
     if (tbSite.Text != "") 
      bConnect.Enabled = true; 
     else 
      bConnect.Enabled = false; 
    } 

    //validation 
    private void tbDirectory_TextChanged(object sender, EventArgs e) 
    { 
     if (tbDirectory.Text != "" && TreeFolder.Nodes.Count != 0) 
      bFolder.Enabled = true; 
     else 
      bFolder.Enabled = false; 
    } 
} 

}

与SP的Dispose检查已经检查,但它说,这(在MapWebs法行 “node.tag = weblist [I] ...如果声明”)

注:来电Microsoft.SharePoint.SPWebCollection.get_Item并没有变赶上返回值 更多信息:http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx#SPDisposeCheckID_130

+0

试运行SharePoint处置者检查器工具。它可能会突出显示事物未被删除的地方。 http://archive.msdn.microsoft.com/SPDisposeCheck。还有一个最佳实践指南可能有所帮助:http://msdn.microsoft.com/en-us/library/aa973248.aspx#sharepointobjmodel__codingtechniques – keyboardP 2011-12-22 11:04:11

+2

您似乎通过将它们置于控制之下来保留x-many'SPWeb'项目标签。这个类实现了'IDisposable'。也许你只是想做太多? – 2011-12-22 11:04:42

+0

@ KeyBoard,我已经检查使用SP Disposer Checkerand多数民众赞成我如何找出内存泄漏方法我上面提到.... – 2011-12-22 11:08:42

回答

3

在这里我看到两个问题:

  1. 您要处理的SPWeb同时遍历SPWeb.Webs,但你保持对TreeNode.Tag的参考。当通过节点的标签访问处置的SPWeb时,SharePoint将再次“打开”web。 =>内存泄漏

  2. 既然你喊你有很多SPWeb对象的同时打开了MapWebs方法递归:

    Root -> open 
        Child 1 -> open 
        Child 1.1 -> open 
         Child 1.1.1 -> open 
        Child 1.2 
        Child 1.3 
        Child 1.4 
    Child 2 
    Child 3 
    
+0

感谢您的“评论”,我想到,就在几个小时前,我不知道如何我可以关闭打开的网络,,, 我做了什么被注释掉了treeNode.tag但它仍然占用太多的内存,同时收集信息, ,我甚至将mapweb方法评论出来,仍然远离正常 – 2011-12-22 14:00:28

+0

您是否试图限制打开的元素?有很多网站/列表/文件夹/项目吗?从我的代码中可以看到,这些项目都保留在内存中。 10个网站10个列表10个文件夹10个文件夹,这取决于内存占用这些项目可能会消耗大量的内存.... – Stefan 2011-12-22 16:46:19

+0

是的,有很多文件,但主要问题是它不处理对象,一旦它创建孩子1.1 ...孩子1.2 .... 我唯一能做的就是改变逻辑或配置对象 – 2011-12-22 16:52:48