C# 窗口窗体处理垃圾邮件



我有一个应用程序,其中包含许多用户控件,每个按钮上都有许多按钮,每个按钮都有一个OnClick事件,该事件执行一些重要操作,然后发送到新的用户控件。

当用户多次单击非常快时,就会出现问题,事件代码在退出到新用户控件之前会执行多次,从而导致问题。

当前的解决方案是禁用事件处理程序第一行上的按钮,但是对每个窗口和处理程序执行此操作会很麻烦,我该怎么办?

编辑:从 Button 派生并覆盖 OnClick 事件是否是一个很好的解决方案,以便它始终检查"工作"变量,如果它是真的,它不会启动事件?像这样:

public class MyButton : Button
{
private static bool isWorking = false;
protected override void OnClick(EventArgs e)
{
    if (!isWorking)
    {
        isWorking = true;
        base.OnClick(e);
        isWorking = false;
    }
    //Else do nothing
}

}

您可以使用

一些timeStamp来延迟两次点击:

DateTime timeStamp;
//this will handle the clicks with the allowed interval being 0.5 second
//Note that a tick is equal to 1/10,000,000 of second.
private void click_Handler(object sender, EventArgs e) {
   if ((DateTime.Now - timeStamp).Ticks < 5000000) return;
   timeStamp = DateTime.Now;
   //your code goes here ....
}

如果希望所有按钮都等到一个按钮的工作完成,请向窗体添加bool isProcessing变量。将每个按钮的工作包装在 if (!isProcessing) 中,并在 if 语句的第一行将该标志设置为 true。然后不要忘记在退出 if 之前将其设置回 false。

我假设您正在异步执行所有这些操作,因为如果它们都在同一个线程中,则表单将在处理工作时锁定。不过,这将解决您的问题。

在敏感操作正在进行时禁用控件是我始终应用的典型解决方案。

但是,由于一个屏幕上可能有相当多的控件受到 UI 中的某些单击或更改的影响,因此我通常将窗体设计为具有专用方法,该方法遍历所有受影响的控件并相应地禁用/启用它们。

像这样:

void EnableControls(bool enable)
{
    foreach (Control ctl in this.Controls)
        ctl.Enabled = enable;
}

同样,您可以将控件分组到相关的存储桶中,以便仅禁用/启用其中一个等。 取决于您的确切需求。

使用计时器还有另一种解决方案 - 禁用按钮,但在 1 秒后启用它。这可以防止紧张的用户多次点击,如果这会对数据造成损害(即每次点击都被视为新操作)。

我会从每个按钮调用相同的函数,然后执行特定的任务:

private void Button_Click(object sender, EventAgrs e)
{
    Button btn = sender;
    btn.disable = true;
    switch (btn.AccessibleName)
    // call specific function for the particular button or do it all here
}

我不确定这是否有效,但只是一个想法......

您可以尝试使用面向方面的方法(例如,在Postsharp的帮助下):

  1. 创建两个方面,一个用于方法输入,一个用于方法退出。在方法条目中,将当前方法标记为"正在处理"(例如,将方法名称添加到哈希集中)。在方法退出中,将该方法标记为"未处理"(将其从哈希集中删除)。然后在方法条目中检查该方法是否正在处理,如果是,则取消该方法(如下所示:https://stackoverflow.com/a/2437794/113858)
  2. 使用此方面标记所有事件处理程序。

相关内容

  • 没有找到相关文章

最新更新