C# 使用MailKit的线程安全GetFolder
我在使用多线程使用MailKit的GetFolder函数时遇到了一个问题。 在这种情况下,我正在运行一个线程来移动我的电子邮件(除其他功能外,它使用GetFolder来查找我的源文件夹和要移动的电子邮件的目标文件夹),另一个线程将在第一个线程运行时搜索电子邮件(第二个线程也使用GetFolder功能) 大多数情况下,我都会收到一份病残手术异常报告 “ImapClient当前正忙于处理命令。” 我如何确保这不会发生??我尝试将所有GetFolder和其他MailKit操作更改为Async,并等待任务完成,但几乎不可能同时完成C# 使用MailKit的线程安全GetFolder,c#,mailkit,C#,Mailkit,我在使用多线程使用MailKit的GetFolder函数时遇到了一个问题。 在这种情况下,我正在运行一个线程来移动我的电子邮件(除其他功能外,它使用GetFolder来查找我的源文件夹和要移动的电子邮件的目标文件夹),另一个线程将在第一个线程运行时搜索电子邮件(第二个线程也使用GetFolder功能) 大多数情况下,我都会收到一份病残手术异常报告 “ImapClient当前正忙于处理命令。” 我如何确保这不会发生??我尝试将所有GetFolder和其他MailKit操作更改为Async,并等待任
我对两个线程使用相同的ImapClient。如上面的评论所述,在这里使用队列可能是正确的解决方案 不过,我想我会发表评论,指出任何想在多线程环境中使用MailKit的人面临的一个重要难题,那就是
ImapClient
和ImapFolder
有一个共享的SyncRoot
属性(ImapClient.SyncRoot
和ImapFolder.SyncRoot
)这意味着用于在多个线程之间同步使用单个IMAP连接
所有的*Async()
方法都会为您锁定SyncRoot
,但非异步方法不会
在IMAP中使用多线程时要记住的另一件事是,IMAP的工作方式是在任何给定时间只允许打开一个文件夹,这意味着如果有一个线程试图将邮件从工作邮件
移动到工作邮件存档
,另一个线程试图搜索个人邮件
,您可能会遇到文件夹选择状态争用的情况,这就是为什么使用队列可能是一个更好的主意
编辑:从2.0版本开始,异步方法不再为您执行任何锁定。你得自己做。这是因为所有异步方法现在都是真正的异步方法,而不是围绕同步API的Task.Run()包装器。正如上面的注释所述,使用队列可能是正确的解决方案 不过,我想我会发表评论,指出任何想在多线程环境中使用MailKit的人面临的一个重要难题,那就是
ImapClient
和ImapFolder
有一个共享的SyncRoot
属性(ImapClient.SyncRoot
和ImapFolder.SyncRoot
)这意味着用于在多个线程之间同步使用单个IMAP连接
所有的*Async()
方法都会为您锁定SyncRoot
,但非异步方法不会
在IMAP中使用多线程时要记住的另一件事是,IMAP的工作方式是在任何给定时间只允许打开一个文件夹,这意味着如果有一个线程试图将邮件从工作邮件
移动到工作邮件存档
,另一个线程试图搜索个人邮件
,您可能会遇到文件夹选择状态争用的情况,这就是为什么使用队列可能是一个更好的主意
编辑:从2.0版本开始,异步方法不再为您执行任何锁定。你得自己做。这是因为所有异步方法现在都是真正的异步方法,而不是围绕同步API的Task.Run()包装器。搜索不会受到内容移动的影响吗?您可以使操作同步,这不是一个选项吗?是的,serach可能会受到移动操作的影响。通过执行此同步来解决问题。就是说,我得到了两个不同的服务,告诉我该做什么(一个告诉我搬家,另一个想读书)。否则,我应该考虑建立一个自己的队列,并通过队列处理操作。实现一个并发队列(在.NET中有一个),它将执行函数,您将一个接一个地传递给它。搜索不会受到东西移动的影响吗?您可以使操作同步,这不是一个选项吗?是的,serach可能会受到移动操作的影响。通过执行此同步来解决问题。就是说,我得到了两个不同的服务,告诉我该做什么(一个告诉我搬家,另一个想读书)。否则,我应该考虑建立一个自己的队列,并通过队列处理操作。实现一个并发队列(在.NET中有一个),它将执行一个接一个地传递给它的函数。