使用MailKit线程安全的GetFolder

时间:2015-03-23 23:36:07

标签: c# mailkit

我使用多个线程使用MailKit的GetFolder函数遇到问题。 案例是他们我正在运行一个线程来移动我的电子邮件(其中包括其他函数使用GetFolder查找我的源文件夹和destionation文件夹以移动电子邮件),另一个线程将搜索第一个正在运行时发送电子邮件(第二个线程也是GetFolder函数)。

我大多数时候都会收到InvalidOperationException告诉我 " ImapClient当前正忙于处理命令。"

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

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

1 个答案:

答案 0 :(得分:4)

正如上面的评论所述,使用队列可能是正确的解决方案。

我想我会发表评论,为任何想要在多线程环境中使用MailKit的人指出一个重要的难题,即ImapClientImapFolder共享{{} 1}} property(SyncRootImapClient.SyncRoot),用于同步多个线程之间单个IMAP连接的使用。

所有ImapFolder.SyncRoot方法都会锁定*Async(),但非Async方法不会。{/ p>

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

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