在两个同步任务之间捕获取消按钮单击

Posted

技术标签:

【中文标题】在两个同步任务之间捕获取消按钮单击【英文标题】:Catching cancel button click between two synchronous tasks 【发布时间】:2021-12-16 20:10:42 【问题描述】:

我有一个正在运行的任务列表,并希望在带有取消按钮的 (WinForms) 表单中显示进度。

我知道,有几个 async 选项,但我有两个限制:任务不能在单独的线程上运行,解决方案必须与 .NET 3.5 兼容(它是程序的插件,我无权访问)。

如果一项任务在取消生效之前完成,那很好。所以我想知道,是否有机会签入同步代码,是否在执行某些任务时鼠标点击按钮?

编辑:这是预期的代码:

foreach (IStep step in Steps)

    if (Cancelled)
        return;
    step.Run();
    ReportProgress(100.0 * completedWeight / totalWeight, step.Description);
    completedWeight += step.Weight;


ReportProgress(100, "Completed");

所以IStep 包含一个Run() 方法,我完全可以在取消之前完成一个步骤。我不知道如何在执行某些步骤以将Cancelled 设置为true 时捕捉鼠标单击“取消”按钮。

【问题讨论】:

执行的代码是什么?是 1 行代码长时间执行还是一个循环或多行代码?如果它是循环或多行并且您找不到合适的方法来执行此操作,则快速而肮脏的方法是添加一个布尔值,在取消单击时将其设置为 true 并检查循环内部 if(cancel == true) break; (或返回您的代码) 这是我的意图,参见上面的编辑。我不知道如何点击按钮将Cancelled 设置为true “任务不能在单独的线程上运行”——这使得提供良好的用户体验变得非常困难。您也许可以显式运行消息循环,但您需要每 50 毫秒左右执行一次,这对我来说听起来像是一个糟糕的解决方案。为什么会有这样的要求? IStep的操作是在一个数据库上进行的,绝对不能处理多次访问。除了在主线程上执行操作外,没有办法阻止主线程随机启动访问。但是,我可能能够在侧线程上启动进度表单并通过主线程对其进行更新(这与通常的方式相反,但我想这很好)。作为初学者,我现在已经删除了取消按钮。 (; @st_stefanov 但是这个click_event只有在我的循环完成后才会执行,不是吗? 【参考方案1】:

显然这里没有“标准”解决方案,所以我们必须跳出框框思考......

假设您有您的应用程序(AddIn 或其他什么都无所谓),但您无法通过按钮控制循环。

你读/写数据库。

在你的循环顶部,它说:

if (Cancelled)
        return;

我们必须替换为:

If(CheckIsCancelled())

您必须找到一种方法来制作一个可以单击的按钮,或者是当前按钮附近的另一个表单,但它必须能够独立于被循环阻止的当前表单运行。

在某种 Config/Util 表中创建一个数据库参数。 例如。 CancelMyLoop - Bit

在该按钮上单击 - 将参数值设置为 true

回到方法:CheckIsCancelled() 它将进入数据库并每次读取该值。

缺点是性能,但你想要不可能的,所以你必须解决这样的解决方法......

您可以创建自己的实现,只是给您一个想法。

【讨论】:

我的旧解决方案有点相似,任务确实保留在主线程上,但进度条确实在另一个线程上运行。这可行,但会使所有进度的处理变得更加困难,如果同步运行,则需要这样做。但是,我接受您的回答,因为这与我最终将使用的最接近。 (:

以上是关于在两个同步任务之间捕获取消按钮单击的主要内容,如果未能解决你的问题,请参考以下文章

从相机捕获图像并在活动中显示

取消绑定 wxPython 中的默认按钮行为

数据流 Task.WhenAll 导致任务被取消异常

如何在 UIAlertView(iOS)中的其他两个按钮(堆叠)之间添加取消按钮

我必须单击两次搜索按钮才能从api获取数据

showBluetoothAccessoryPickerWithNameFilter:completion: 取消按钮