Windows窗体应用程序的内存使用量太大

时间:2011-12-22 10:56:33

标签: c# .net sharepoint memory sharepoint-2007

我做了一个应用程序从给定的sharepoint站点下载一个文件夹,但是当我点击Connect按钮时它消耗的内存超过600,000K,任何人都可以给出建议来改进我的代码吗?

我试图调试我的表单,问题出现在方法“private void MapWebs(SPWebCollection webList,TreeNode webparentNode)”中,它一次又一次地调用自己来遍历每个网络及其子网,但我检查了当我点击连接时它开始,它通过代码行

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

内存使用量从20,000 K到40,000 K(大约)

要运行此应用程序,您必须在您的PC上安装sharepoint,此类链接的示例就在此链接上,

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 checker进行了检查,但它说明了这一点(在MapWebs方法行“node.tag = weblist [i] ...和if语句”)

  

注意:调用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

1 个答案:

答案 0 :(得分:3)

我在这里看到两个问题:

  1. 您正在迭代SPWeb时处置SPWeb.Webs,但您在TreeNode.Tag上保留了引用。通过节点的标记访问已处置的SPWeb时,SharePoint将再次“打开”Web。 =&GT;记忆泄漏

  2. 由于您正在递归调用MapWebs方法,因此您同时打开了很多SPWeb个对象:

    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