如何在Silverlight/WCF中取消异步操作?

4
我正在从我的Silverlight应用程序中调用异步服务,并希望在调用后能够取消该调用。一旦服务完成(即如果e.Cancelled Then),有一个选项可以取消,但是如何在调用后将其设置为true?如何取消该异步调用?
让我澄清一下...我想做的是连续调用同一方法两次,并将最后一次调用的结果放入我的集合中。如果我连续调用异步方法,则不能保证第二次调用会先返回,因此我可能最后得到第一次调用的结果,并且在我的集合中得到错误的结果。所以我想做的是在进行第二次调用时取消第一次调用,这样我就不会从第一次调用中得到结果。鉴于完成事件参数中有一个已取消的标志,我认为应该能够做到这一点。但是怎么做呢?
2个回答

5

异步的含义是...将数据传输交给远端服务器后,不需要等待服务器处理完成就可以返回。

基本上服务器会一直运行下去,但你不需要等待响应。断开你的服务已完成事件处理程序并假装从未调用过它。这将产生取消操作的效果。

如果你真的需要取消正在进行的服务器操作,你需要向服务器发出另一个请求来取消第一个请求。假设第一个请求非常缓慢,则可能有可能。

更新(因为问题改变)

在你指定的情况下,如果第二个请求进来,要取消正在进行的操作取决于服务器,而不是客户端。e.Cancelled是在服务器端设置的。

然而... :)

你暴露了一个客户端可用性问题。难道你不应该在空闲延迟过后再发送任何服务请求吗?这样快速选择就不会导致多次服务调用。

还有... :>

你可能还想向你的服务调用发送一个序列号,并将其作为结果的一部分返回。然后你就知道它是最新的请求还是不是。


我正在将开始和结束日期绑定到用户控件,用户可以通过拖动任一端或通过拖动整个控件来更改开始或结束日期。每次更改开始或结束日期时,我都会调用服务。当他们拖动条并更改两个日期时,我会得到两组结果,第二组是正确的...所以没有空闲延迟。也许这不是最好的方法,但是... - Barry Franklin
您需要在中间某处缓存调用,而不是太频繁地调用服务(考虑一下未来的 Azure 账单!:)。目前它就像一个自动完成框,每次按键都会调用(它们通常会等待上次按键后0.5秒才调用)。 - iCollect.it Ltd
@Allen Ho:如果您有需要aspNetCompatibilityEnabled="true"的服务,请将它们放在单独的IIS服务/站点中。 - iCollect.it Ltd

1

听起来你真正想做的是忽略除最近调用之外的所有响应。

使用请求设置唯一ID(可以是请求号码、Guid、时间戳或其他),并确保服务发送相同的值。保留最近请求的ID并忽略不匹配该ID的响应。

这比取消第一个请求更安全,因为如果服务在取消请求发生之前已经开始发送响应,则仍会出现错误条件。


我想出了如何避免进行这些调用,但是那个 ID 的想法听起来很不错,我得记住以备将来使用。谢谢。 - Barry Franklin
这是一个很好的想法,可以跟踪最近的Davy8通话,但是不改变服务器端代码并通过网络传递ID,是否有可能实现这一点呢?我的意思是,是否可以通过某些客户端技巧来实现这一点? - Narek Malkhasyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接