同步Exchange WebService托管API方法调用

时间:2014-03-05 11:17:40

标签: c# multithreading asynchronous exchange-server exchangewebservices

我编写了一个监听器类,用于创建HTTP侦听器并订阅其URL以推送订阅(使用EWS托管API在Inbox上的新邮件事件上),接收通知,处理邮件,然后将这些邮件移动到“已删除邮件”文件夹。我还写了一个轮询器,定期检查收件箱内遗留的任何邮件,处理它们,然后将它们移动到Deleted Items文件夹。监听器和轮询器以不同的线程运行。

我已经使用锁来同步这些线程。锁定功能经过测试可以正常工作。但是由于锁定,我得到了一些不受欢迎的行为。

考虑监听器收到推送通知。它开始处理它。同时,轮询器启动并获得锁定。现在,当侦听器尝试获取锁时,它会发现轮询器已经获取了锁。所以它一直等到锁被释放。假设监听器执行直到指令INSTR-1并继续等待。现在,poller正在处理收件箱中的所有邮件,比如3-5分钟。之后,poller释放锁定。在3-5分钟内,交换继续发送推送通知,但是由于第一个侦听器线程停留在INSTR-1,因此.NET运行时不再调度侦听器线程。但是一旦poller发布锁定,就会调度所有线程。但由于它们的相应邮件已经被轮询器处理并移动到Deleted Items文件夹,因此这些侦听器线程会在EmailMessage.Bind()方法上抛出异常“在商店中找不到指定的对象。”。由于我现在已经很好地分析了这种行为,并且我确切地知道为什么会发生这种异常,我可以继续抑制这些异常(例如使用空catch块)。

但是我想知道,

  1. 如果有任何方法可以让Exchange Server在轮询器启动后不发送任何推送通知,或者换句话说,那些已经由EWS托管API调用ExchangeService.FindItems()检索的邮件由poller制作。

  2. 如果有任何标准/ Microsoft建议的方法来处理此类问题

  3. 我们可以可视化监听器和轮询程序以及执行行为,如下所示: enter image description here

1 个答案:

答案 0 :(得分:1)

要回答#1,简答为否。接收推送通知没有PAUSE功能。您甚至无法暂时取消订阅,因为没有取消订阅推送。 (并非你很可能想要。)

要回答#2,为MS发言是我的自命不凡,但我读过的所有内容都表明你应该在听众和投手者中做最少量的工作。所有这些线程应该做的是让ItemId参与您感兴趣的通知或电子邮件,并排队等待进一步处理(获取,移动,删除等)持有锁定3-5分钟一般不是一个好习惯。 (如果可能的话,锁应该保持毫秒。)如果你对ItemIds进行排队并且有一个单独的线程(或多个线程)来处理它们在轮询器/监听器之外,那么这将是一个更强大的解决方案,恕我直言。