0

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

大多数时候我收到一个 InvalidOperationException 告诉我“ImapClient 当前正忙于处理命令”。

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

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

4

1 回答 1

5

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

不过,我想我会发表评论,为任何想要在多线程环境中使用 MailKit 的人指出一个重要的难题,那就是它具有共享属性 ( ImapClientand ) ,用于同步使用多个线程之间的单个 IMAP 连接。ImapFolderSyncRootImapClient.SyncRootImapFolder.SyncRoot

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

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

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

于 2015-03-25T15:54:03.533 回答