C# 如何在事件';她又打电话来了?

C# 如何在事件';她又打电话来了?,c#,winforms,events,async-await,C#,Winforms,Events,Async Await,我知道这可能是一个我应该能够很容易地谷歌,但只是不知道什么搜索的时刻 基本上,我有一个引发的事件,当它仍在执行时,它可能会再次引发。如果发生这种情况,我想立即终止之前的任何执行 在本例中,我讨论的是DataGridView的SelectionChanged事件。在我将异步编程引入这个项目之前,没有任何问题。但现在我发现,当该方法等待异步调用的结果时,它可能会再次引发。新的调用可能会在原始调用之前完成,从而导致UI状态不一致。类似这样的情况如何: private CancellationT

我知道这可能是一个我应该能够很容易地谷歌,但只是不知道什么搜索的时刻

基本上,我有一个引发的事件,当它仍在执行时,它可能会再次引发。如果发生这种情况,我想立即终止之前的任何执行


在本例中,我讨论的是DataGridView的SelectionChanged事件。在我将异步编程引入这个项目之前,没有任何问题。但现在我发现,当该方法等待异步调用的结果时,它可能会再次引发。新的调用可能会在原始调用之前完成,从而导致UI状态不一致。

类似这样的情况如何:

    private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    public async void OnMainThread()
    {
        cancellationTokenSource.Cancel();
        var newCts = new CancellationTokenSource();
        cancellationTokenSource = newCts;
        try
        {
            var result = await AsyncOp(newCts.Token);
            if (!newCts.IsCancellationRequested)
            {
                // Update UI
            }
        }
        catch (OperationCanceledException)
        {
            // Ignore
        }
    }

    public async Task<int> AsyncOp(CancellationToken cancel)
    {
        // Do the async work
        return 0;
    }
private CancellationTokenSource CancellationTokenSource=new CancellationTokenSource();
mainthread()上的公共异步void
{
cancellationTokenSource.Cancel();
var newCts=新的CancellationTokenSource();
cancellationTokenSource=newCts;
尝试
{
var结果=等待异步操作(newCts.Token);
如果(!newCts.iscancellationrequest)
{
//更新用户界面
}
}
捕获(操作取消异常)
{
//忽略
}
}
公共异步任务异步操作(CancellationToken cancel)
{
//执行异步工作
返回0;
}

像这样的东西怎么样:

    private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    public async void OnMainThread()
    {
        cancellationTokenSource.Cancel();
        var newCts = new CancellationTokenSource();
        cancellationTokenSource = newCts;
        try
        {
            var result = await AsyncOp(newCts.Token);
            if (!newCts.IsCancellationRequested)
            {
                // Update UI
            }
        }
        catch (OperationCanceledException)
        {
            // Ignore
        }
    }

    public async Task<int> AsyncOp(CancellationToken cancel)
    {
        // Do the async work
        return 0;
    }
private CancellationTokenSource CancellationTokenSource=new CancellationTokenSource();
mainthread()上的公共异步void
{
cancellationTokenSource.Cancel();
var newCts=新的CancellationTokenSource();
cancellationTokenSource=newCts;
尝试
{
var结果=等待异步操作(newCts.Token);
如果(!newCts.iscancellationrequest)
{
//更新用户界面
}
}
捕获(操作取消异常)
{
//忽略
}
}
公共异步任务异步操作(CancellationToken cancel)
{
//执行异步工作
返回0;
}

在引发SelectionChanged时,可能会将任务放入队列中?异步操作是否接受?请共享您的代码,直到用户在执行由
SelectionChanged
触发的过程时不应选择任何其他内容?如果不是,那么它就不是异步的。这些选择更改是否意味着网格其他值的更改?还是其他控制?数据本身?如果是这样的话,它可能并不意味着是异步的。用户是否可以触发由
SelectionChange
触发的异步过程所影响的一个或多个相同元素的选择更改和/或值更改?如果是的话,就不是异步的。如果表单关闭怎么办?这会对异步进程的操作产生影响吗?如果该过程是由选择触发的,则更改意味着在其他地方更改某些内容(不影响当前用户输入),并且这些更改也意味着按其性质/结果集顺序进行,则使用顺序代理(队列)处理这些更改。这些程序是否可以在不造成伤害的情况下中断?然后使用CancellationTokenSource通知任务顺利退出,因为知道运行这些任务的UI线程中的元素可能不再可访问。可能在引发SelectionChanged时将任务放入队列?异步操作是否接受?请,共享您的代码,直到用户在执行由
SelectionChanged
触发的过程时不应该选择任何其他内容吗?如果不是,那么它就不是异步的。这些选择更改是否意味着网格其他值的更改?还是其他控制?数据本身?如果是这样的话,它可能并不意味着是异步的。用户是否可以触发由
SelectionChange
触发的异步过程所影响的一个或多个相同元素的选择更改和/或值更改?如果是的话,就不是异步的。如果表单关闭怎么办?这会对异步进程的操作产生影响吗?如果该过程是由选择触发的,则更改意味着在其他地方更改某些内容(不影响当前用户输入),并且这些更改也意味着按其性质/结果集顺序进行,则使用顺序代理(队列)处理这些更改。这些程序是否可以在不造成伤害的情况下中断?然后使用CancellationTokenSource来通知任务很好地退出,知道运行它们的UI线程中的元素可能不再可访问。非常好!如果(!newCts.IsCancellationRequested)您可以只调用
newCts.Token.throwifccancellationrequested(),更简洁一点。这很有效。。。虽然很奇怪,但接球挡似乎从未被击中。这让我想知道这一变化是否对它产生了如此轻微的影响,以至于它自然地按正确的顺序排列。此外,对于任何未来阅读此文章的人来说,如果他们认为AsyncOp必须使用取消令牌才能工作,我实际上没有更新我的AsyncOp以使用取消令牌。我调用的web服务无论如何都会完成运行,但这没什么大不了的。主要的是忽略结果。非常好!如果(!newCts.IsCancellationRequested)
您可以只调用
newCts.Token.throwifccancellationrequested(),更简洁一点。这很有效。。。虽然很奇怪,但接球挡似乎从未被击中。这让我想知道这一变化是否对它产生了如此轻微的影响,以至于它自然地按正确的顺序排列。此外,对于任何未来阅读此文章的人来说,如果他们认为AsyncOp必须使用取消令牌才能工作,我实际上没有更新我的AsyncOp以使用取消令牌。我调用的web服务无论如何都会完成运行,但这没什么大不了的。主要的是忽略结果。