Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 同步Exchange WebService托管API方法调用_C#_Multithreading_Asynchronous_Exchange Server_Exchangewebservices - Fatal编程技术网

C# 同步Exchange WebService托管API方法调用

C# 同步Exchange WebService托管API方法调用,c#,multithreading,asynchronous,exchange-server,exchangewebservices,C#,Multithreading,Asynchronous,Exchange Server,Exchangewebservices,我编写了一个侦听器类,它创建一个HTTP侦听器并订阅其URL以推送订阅(使用EWS托管API在收件箱上的新邮件事件上),接收通知,处理邮件,然后将这些邮件移动到“已删除邮件”文件夹。我还编写了一个轮询器,定期检查收件箱中的任何邮件,对其进行处理,然后将其移动到“已删除邮件”文件夹。侦听器和轮询器在不同的线程中运行 我已经使用锁同步了这些线程。锁功能经过测试,工作正常。然而,由于锁定,我得到一些不想要的行为 假设侦听器收到推送通知。它开始处理它。同时,轮询器启动并获取锁。现在,当侦听器尝试获取锁时

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

我已经使用锁同步了这些线程。锁功能经过测试,工作正常。然而,由于锁定,我得到一些不想要的行为

假设侦听器收到推送通知。它开始处理它。同时,轮询器启动并获取锁。现在,当侦听器尝试获取锁时,它发现轮询器已经获取了锁。所以它会一直等到锁被释放。假设侦听器一直执行指令
INSTR-1
,然后继续等待。现在,poller正在处理收件箱中的所有邮件,大约3-5分钟。之后,poller释放锁。在这3-5分钟内,exchange继续发送推送通知,但由于第一个侦听器线程卡在
INSTR-1
上,.NET运行时不再发送侦听器线程。但一旦轮询器释放锁,所有线程都将被调度。但是,由于轮询器已经处理了相应的邮件并将其移动到“已删除邮件”文件夹中,这些侦听器线程在
EmailMessage.Bind()
method上抛出异常“指定的对象未在存储中找到”。由于我现在已经很好地分析了这个行为,并且我确切地知道了这个异常发生的原因,所以我可以继续抑制这些异常(比如使用空的
catch
块)

但是我想知道

  • 如果有任何方法可以使Exchange Server在轮询器启动后不发送任何推送通知,或者换句话说,对于那些已由轮询器进行的EWS托管API调用
    ExchangeService.FindItems()
    检索到的邮件

  • 是否有任何标准/Microsoft建议的方法来处理此类问题

  • 我们可以可视化侦听器和轮询器过程以及执行行为,如下所示:

    要回答#1,简短的回答是否。没有用于接收推送通知的暂停功能。你甚至不能暂时取消订阅,因为推送没有取消订阅。(并不是说你很可能想这么做。)


    回答#2,我代表微软发言是自命不凡的,但我所读到的所有内容都表明,你应该在听众和民意调查者身上做最少的工作。所有这些线程应该做的是获取您感兴趣的通知或电子邮件中涉及的ItemId,并将其排队等待进一步处理(获取、移动、删除等),通常持有锁3-5分钟不是一个好做法。(锁应该保持毫秒,如果可能的话。)如果您对ItemID进行排队,并且在轮询器/侦听器之外有一个单独的线程(或多个线程)来处理它们,这将是一个更健壮的解决方案,IMHO。

    是的,非常正确,我没有想到,我认为这应该是与设计方法相关的更正,但是我想知道1。如果使用空catch块抑制异常,是否可以?(至少是我已经建造的)和2。在当前的解决方案中,您能看到任何暂时的小的设计改进吗?抑制那些特殊的异常不是问题。事实上,您可能会遇到许多“找不到对象”的情况,因为Exchange的内部工作流喜欢创建和销毁许多对象,即使它们实际上可能只处理单个电子邮件项目。我的应用程序特别处理约会,一个会议邀请和接受周期可能会在商店中创建3个不同的ItemID,其中2个在我输入通知时不再存在。所以我只是抱着“摆脱困境”的态度,认为“最后一个站着的人”才是我真正关心的。我只是更多地考虑了你的方法。我觉得这会导致一些重复,为了避免重复,我使用了锁,尽管没有我们的方法。因此,通过UR方法,让我们考虑侦听器和民意测验器在不同的线程中运行,从收件箱中取出邮件,然后将其添加到键为“代码> ITEMID < /代码>的字典中。现在假设侦听器将
    item1
    添加到字典中,在另一个线程中运行的处理器接收该邮件并开始处理它。同时,轮询器将无法将相同的
    item1
    添加到字典……。处理器结束处理,从Exchange Server中删除邮件,并从字典中删除
    ItemId
    。在此之后,轮询器将永远无法在交换中找到item1。但在轮询器开始提取收件箱中的所有邮件和尝试在字典中添加
    item1
    之间有一段时间。现在,如果处理器在此期间从字典中删除项,轮询器将成功地将
    item1
    重新添加到字典中,因为它是由处理器删除的……。下次处理器尝试重新处理
    item1
    时,它将无法获取与
    item1
    ItemId
    对应的完整邮件,这将引发异常。我想我将不得不在那里使用另一个空的捕捉区。有什么评论吗?这就是你实现它的方式吗?