使用 MailKit 的线程安全 GetFolder

grm*_*hel 0 c# mailkit

我在使用多线程使用 MailKit 的 GetFolder 函数时遇到问题。情况是他们我正在运行一个线程来移动我的电子邮件(其中一个函数确实使用 GetFolder 来查找我的源文件夹和目标文件夹以移动电子邮件),另一个线程将搜索电子邮件第一个正在运行(第二个线程也执行 GetFolder 函数)。

大多数情况下,我都会收到 InvalidOperationException 异常,告诉我“ImapClient 当前正忙于处理命令”。

我怎样才能确保这不会发生?我尝试将所有 GetFolder 和其他 MailKit 操作更改为异步,并等待任务完成,但没有任何运气或多或少同时执行此操作。

我为两个线程使用相同的 ImapClient。

jst*_*ast 5

正如上面的评论中提到的,在这里使用队列可能是正确的解决方案。

我想,我会发表评论,不过,要指出的拼图重要的一块任何人想要在多线程环境中是使用MailKitImapClientImapFolder有一个共同的SyncRoot属性(ImapClient.SyncRootImapFolder.SyncRoot),是为了用于同步使用多个线程之间的单个 IMAP 连接。

所有*Async()方法都会SyncRoot为您锁定,但非异步方法不会。

在 IMAP 中使用多线程时要记住的另一件事是,IMAP 的工作方式是在任何给定时间只允许打开 1 个文件夹,这意味着如果您有 1 个线程试图将消息从另一个线程WorkMail移入WorkMailArchive另一个线程尝试搜索时PersonalMail,您可能会遇到文件夹选择状态竞争条件,这就是为什么使用队列可能是一个更好的主意。

编辑:从 2.0 版本开始,异步方法不再为您做任何锁定。你必须自己做。这是因为所有 Async 方法现在都是真正的异步,而不是围绕同步 API 的 Task.Run() 包装器。