我编写了一个侦听器类,它创建一个HTTP侦听器,并订阅它的URL以推送订阅(在使用EWS托管API的收件箱上的新邮件事件上),接收通知、处理邮件,然后将这些邮件移动到“已删除邮件”文件夹。我还编写了一个轮询器,它定期检查收件箱中遗漏的任何邮件,对它们进行处理,然后将它们移到已删除的邮件文件夹中。侦听器和轮询器在不同的线程中运行。
我已经使用锁同步了这些线程。并对锁功能进行了测试,使其工作良好。然而,由于锁定,我得到了一些不想要的行为。
考虑侦听器收到推送通知。它开始处理它。同时,波勒开始,它获得了锁。现在,当侦听器试图获取锁时,它会发现锁已经被轮询器获取。所以它一直等到锁被释放。假设侦听器执行到指令INSTR-1并继续等待。现在波勒正在处理收件箱里的所有邮件,比如3到5分钟。在那之后,波勒释放锁。在这3-5分钟内,exchange继续发送推送通知,但是由于第一个侦听器线程被卡在INSTR-1上,所以.NET运行时不再分派侦听器线程。但是,一旦poller释放锁,所有线程就会被分派。但是,由于它们的相应邮件已经由计票器处理并移动到“已删除邮件”文件夹,这些侦听器线程抛出异常“指定的对象在存储区中找不到”。关于EmailMessage.Bind()方法由于我现在已经很好地分析了这个行为,并且我确切地知道了为什么会出现这个异常,所以我可以继续抑制这些异常(比如使用空的catch块)。
但是我想知道,
ExchangeService.FindItems()。我们可以将侦听器和轮询程序以及执行行为可视化如下:

发布于 2014-03-06 01:19:43
要回答#1,简短的回答是否定的。没有接收推送通知的暂停功能。您甚至不能暂时取消订阅,因为没有取消订阅的推送。(并不是说你很有可能想要这样做。)
要回答#2,我代表MS发言是自命不凡的,但我所读到的一切都表明,你应该在你的听众和计票者中做最少的工作。所有这些线程应该做的是让ItemId参与到您感兴趣的通知或电子邮件中,并排队等待进一步的处理(Get、Move、Delete等)。一般情况下,保持锁3-5分钟并不是一个好做法。(如果可能的话,锁应该保持毫秒。)如果您将ItemIds排队,并有一个单独的线程(或多个线程)在poller/listener之外处理它们,那将是一个更健壮的解决方案,IMHO。
https://stackoverflow.com/questions/22196182
复制相似问题