2011-12-22 65 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