在C#中执行重方法时取消按钮单击事件

时间:2016-12-22 07:54:55

标签: c# events

我想在C#中执行任何繁重的方法时取消按钮点击事件。 让我们说有以下方法和事件:

private void Submit()
{
    //This method requires 5 seconds and it is blocking method   
}
private void button_Click(object sender, EventArgs e)
{
    //Some code here
}

当我在执行Submit方法时单击按钮时,按钮单击事件不会触发,而是在完成Submit方法的执行后触发它。

我想在执行Submit方法时单击时取消此事件。 我无法禁用此按钮,因为我的应用程序包含许多此类按钮。 我还想阻止在执行Submit方法期间启动的所有事件被触发,并允许在执行Submit方法之后触发所有事件。

请建议任何解决方案或解决方法来实现约会任务。

5 个答案:

答案 0 :(得分:1)

如果使用async启动新任务,则可以在执行提交时调用cancel方法。

private async Task Submit()
{
    await Task.Factory.StartNew(() => 
    {
        // Blocking code, network requests...
    });
}

请等待https://msdn.microsoft.com/en-us/library/mt674882.aspx等待异步参考,并且频道5还有一些关于它的精彩视频https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async

如果你想在触发“取消”时停止“提交”,我建议使用CancellationEventSource取消任务,看看:

using System.Threading.Tasks;

private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

private async Task Submit()
{
    var cancellationToken = this.cancellationTokenSource.Token;
    await Task.Factory.StartNew(() => 
    {
        cancellationToken .ThrowIfCancellationRequested();

        // Blocking code, network requests...

    }, this.cancellationTokenSource.Token); 
}

private void button_Click(object sender, EventArgs e)
{
    this.cancellationTokenSource.Cancel();
}

查看有关CancellationTokenSource和Task https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

的这篇msdn文章

编辑1:

  

我不想再停止Submit()了。我想取消这个活动   在执行Submit()期间,允许事件被触发   完成Submit()

创建一个任务并等待它完成:

private Task submitTask;

private void Submit()
{
    this.submitTask = Task.Factory.StartNew(() => 
    {
        // Some Code
    } 
}
private async void button_Click(object sender, EventArgs e)
{

    // Awaiting will prevent blocking your UI    
    await this.submitTask;

    // Some Code    
}

答案 1 :(得分:0)

               delegate void submitdelegate();
                public partial class Form1 : Form
                  {
                   public Form1()
                        {
                          InitializeComponent();
                         }
                   IAsyncResult ia;
              private void Form1_Load(object sender, EventArgs e)
                {
                submitdelegate sd=Submit;
              ia=sd.BeginInvoke(()=>{},null,null);

                 }
                 private void Submit()
                {

                   }

    void button_Click(object sender, EventArgs e)
    {
      if(ia.IsCompleted)
       {//run all the things you want here
          }
        }

在Iasyncresult中创建一个实例会让你委托完成执行。 http://www.dotnetcurry.com/ShowArticle.aspx?ID=634

答案 2 :(得分:0)

您可以使用Task来实现这一目标。

CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
CancellationToken _ct;

private void Submit()
{
     _ct = cancellationTokenSource.Token;
    var task = Task.Factory.StartNew(() =>
    {
      _ct.ThrowIfCancellationRequested();
      //your code here
    }, _ct);


}
private void button_Click(object sender, EventArgs e)
{
    //Some code here
   _cancellationTokenSource.Cancel();
}

CancellationToken是一个对象,允许您向“任务”信息发送应该取消任务的信息。此外,在Task内,请确保您ThrowIfCancellationRequested以确保此任务停止。

在我的例子中,button_click是取消按钮。

您可以在此处找到更多信息:https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

答案 3 :(得分:0)

如果对Submit()的通话当前有效,您的目标是阻止按钮产生任何效果。

这样做:

(1)将调用Submit()的{​​{1}}调用async作为单独的任务调用{<1}}:

Submit()

(2)在类中添加一个布尔字段,用于检查当前是否正在执行private async Task SubmitAsync() { await Task.Run(() => Submit()); }

Submit()

(3)将您的按钮点击处理程序更改为private bool submitIsActive = false; 并在等待async之前检查submitIsActive标记:

SubmitAsync()

乍一看,您可能会认为存在竞争条件,其中private async void button_Click(object sender, EventArgs e) { if (!submitIsActive) { submitIsActive = true; await SubmitAsync(); submitIsActive = false; } } 在一个线程中设置为true,但在另一个线程中检查。事实并非如此,因为只会从UI线程调用submitIsActive方法。

另请注意,此方法不允许您取消对button_Click()的通话 - 但我认为您没有要求这样做。

答案 4 :(得分:-2)

如果在Submit()方法的持续时间内取消订阅点击事件中的按钮呢?按钮太多了?