【问题标题】:How to cancel long-running operations that require to start on the server side (rather than initiated by the client)如何取消需要在服务器端启动的长时间运行的操作(而不是由客户端启动)
【发布时间】:2011-10-22 09:10:55
【问题描述】:

我有一个类,它根据在对象状态更改之前引发事件以及在状态更改后引发事件的约定公开可取消事件。发布者(服务器)公开的更改前事件的格式为StateChanging,参数为CancelEventArgs,而更改后的事件格式为StateChanged。这为事件的订阅者(客户端)提供了在操作开始之前取消操作的能力。

现在我更改了其中一项操作,使其成为一项长时间运行的操作,并且我想让订阅者在操作开始后也可以取消操作(并且还可以了解操作进度)。我想到了event-based asynchronous pattern

问题是我想保留更改前和更改后事件模式,因为它是发布者在某些时候需要操作,而在异步模式中,在我看来是客户端特别要求异步运行某个操作。另一种可能性(但对我来说似乎并不优雅)可能是让服务器公开一个事件(例如OperationRequired),让客户端知道需要在服务器端完成什么并相应地调用RunOperationAsync() 方法.请发表评论并添加您的建议。

【问题讨论】:

    标签: c# events asynchronous cancellation


    【解决方案1】:

    对于由 UI 控制的操作,通常首选基于事件的异步模式。替代方案,异步编程模型,通常是服务器或库 API 的首选。如果您选择实施 EAP,那很好。

    看看BackgroundWorker 实现——它是支持取消等功能的 EAP 的最佳示例。它通过标准的CancelAsync() 方法提供取消。

    【讨论】:

    • 我对 BackgroundWorker 有所了解,但我看不到使用它的正确方法,因为我的服务器在某个时间点启动了未明确请求的操作。我尝试更好地解释:客户端请求某个操作X,服务器正常执行操作X;但有时服务器(根据其状态)需要在 X 之前执行操作 Y,并且由于 Y 可以长时间运行,服务器应该通知客户端它正在启动 Y 并允许客户端最终取消它(这反过来也将取消 X)。
    • 如果您的客户端事先知道它是否准备好等待 Y,它可以在调用您的 xxxAsync 方法之前在您的服务器对象上设置一个属性,例如 bool CancelIfYRequired。或者它可以将其作为额外参数传递。同样,您可以向xxxCompletedEventArgs 类添加一个属性,以指示操作何时因这种情况而被取消。您的 CancelAsync 方法应该支持在执行 Y 或 X 时取消。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 2020-05-06
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多