C# 如何清除IEnumerable<;ImapX.消息>;?

C# 如何清除IEnumerable<;ImapX.消息>;?,c#,multithreading,imap,ram,imapx,C#,Multithreading,Imap,Ram,Imapx,我下载了所有的邮件并检查了它们的附件。他们正在给公羊加油。我被称为线程中的代码。我正在尝试使用client.Dispose()和GC.Collect(),但没有帮助:(( 首先,当Message对象在当前范围内仍处于活动状态时,调用GC.Collect(); 您正在调用client.Dispose();但使用语句调用的另一个问题实际上是相同的,因为它只用于下一个代码: var client = new ImapClient(hostname, true) try { ... } fin

我下载了所有的邮件并检查了它们的附件。他们正在给公羊加油。我被称为线程中的代码。我正在尝试使用client.Dispose()和GC.Collect(),但没有帮助:((


首先,当
Message
对象在当前范围内仍处于活动状态时,调用
GC.Collect();

您正在调用
client.Dispose();
但使用
语句调用
的另一个问题实际上是相同的,因为它只用于下一个代码:

var client = new ImapClient(hostname, true)
try
{
    ...
}
finally
{
    if (client != null)
    {
        ((IDisposable)client).Dispose();
    }
}
您的示例没有内存泄漏,GC将在下一个
collect()
上自动收集
Message
对象

如果要强制垃圾收集,可以在使用
block的
之后调用
GC.Collect()
,但这实际上是一种bat实践。可以通过调用Collect强制垃圾收集,但大多数情况下,应该避免这种情况,因为它可能会产生性能问题

如果确实需要在循环中收集对象,请尝试使用property或
WaitForPendingFinalizers()
方法。完整代码如下所示:

foreach (Folder myfolder in folders)
{

    var messages = client.Folders[i].Search("ALL");
    i++;
    foreach (var message in messages)
    {
        var attachments = message.Attachments;
        if (attachments.Count() > 0)
            if (!Directory.Exists(folder + @"\" + login))
            {
                DirectoryInfo di = Directory.CreateDirectory(folder + @"\" + login);// Try to create the directory.
            }
        foreach (var attachment in attachments)
        {
            attachment.Download();
            attachment.Save(folder + @"\" + login);
        }
        attachments = null;
    }

    messages = null;

    // performance killer
    GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
    GC.Collect(2);
    GC.WaitForPendingFinalizers();
    GC.Collect(2); 
} 

请注意,这不是生产代码,而是解决您的问题的组合解决方法。

您不应该调用
GC.Collect()
除非你有防御性地知道自己在做什么。这不会有帮助,因为当你的程序占用大量RAM时,CLR会运行GC本身。如果你看到内存消耗在增长,那么似乎你有非托管资源泄漏

我根据ImapX项目编辑了我的代码:几乎没有需要手动处理的资源。因此,这里唯一能做的就是对路径进行实习。您还应该实习登录名和密码,因为您的代码没有创建其他字符串。经过几项改进后,将如下所示:

public void DownloadAllAttachments()
{
    using (var client = new ImapClient(hostname, true))
    {
        if (!client.Connect( /* optional, use parameters here */) || !client.Login(login, pass))
            return;

        string path = string.Intern(Path.Combine(folder, login));
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        foreach (Folder myfolder in client.Folders)
        {
            foreach (var message in myfolder.Search())
            {
                foreach (var attachment in message.Attachments)
                {
                    attachment.Download();
                    attachment.Save(path);
                }
            }
        }
    }
}

GC未收集垃圾和RAM被越来越多地填充@ааааСаааааСааааааааааааааа1072这是解决您的问题的一种方法。并且不是IMElement IDisposabe,因此您的代码将无法编译。@VadimMartynov感谢您的评论,经过后期编辑。当枚举SPWeb时,我与TS处于相同的情况。当您这样做时,您还应该处理web本身,因为
foreach
语句仅处理集合。
public void DownloadAllAttachments()
{
    using (var client = new ImapClient(hostname, true))
    {
        if (!client.Connect( /* optional, use parameters here */) || !client.Login(login, pass))
            return;

        string path = string.Intern(Path.Combine(folder, login));
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        foreach (Folder myfolder in client.Folders)
        {
            foreach (var message in myfolder.Search())
            {
                foreach (var attachment in message.Attachments)
                {
                    attachment.Download();
                    attachment.Save(path);
                }
            }
        }
    }
}