我想在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方法之后触发所有事件。
请建议任何解决方案或解决方法来实现约会任务。
答案 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()方法的持续时间内取消订阅点击事件中的按钮呢?按钮太多了?