取消已初始化并在另一个事件处理程序方法中运行的任务

本文关键字:方法 运行 任务 程序 事件处理 初始化 另一个 取消 | 更新日期: 2023-09-27 18:10:01

我正在构建一个c#/Windows窗体应用程序。

在窗体上各种按钮的click事件处理程序中,我初始化并启动了不同的任务。但是,对于某些按钮单击,我希望取消由某些其他单击事件处理程序启动的仍在运行的任何任务。

下面是我的代码。到目前为止,第二个版本是我尝试让第二个方法取消由第一个方法启动的正在运行的任务,但是它还不起作用。如何取消正在运行的任务?

示例代码(尚未添加取消令牌):

private void btnFrontDoorCycle_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        // Do function 1
        // Do function 2
        // etc
    });
}
private void btnFrontDoorClose_Click(object sender, EventArgs e)
{
    // If task started in btnFrontDoorCycle_Click is running, cancel it here
    Task.Factory.StartNew(() =>
    {
        // Do function 5
        // Do function 6
        // etc
    });
}

示例代码(我添加cancellationtokens的尝试不起作用):

private CancellationTokenSource cancellationTokenSource;
private void btnFrontDoorCycle_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        // Do function 1
        // Do function 2
        // etc
    }, cancellationToken);
}
private void btnFrontDoorClose_Click(object sender, EventArgs e)
{
    // If task started in btnFrontDoorCycle_Click is running, cancel it here
    if (this.cancellationTokenSource != null)
    {
        this.cancellationTokenSource.Cancel();
    }
    this.cancellationTokenSource = new CancellationTokenSource();
    CancellationToken cancellationToken = this.cancellationTokenSource.Token;
    Task.Factory.StartNew(() =>
    {
        // Do function 5
        // Do function 6
        // etc
    });
}

取消已初始化并在另一个事件处理程序方法中运行的任务

您需要检查令牌是否已取消。下面是我写的一小段代码,只是为了检查它是如何工作的。希望你能从中提取出你需要的东西…

internal class TaskCancellationProblem
{
    private CancellationTokenSource tokenSource;
    private CancellationToken token;
    public TaskCancellationProblem()
    {
        ResetSourceAndToken();
    }
    private void ResetSourceAndToken()
    {
        tokenSource = new CancellationTokenSource();
        token = tokenSource.Token;
    }
    public void RunFirstTask()
    {
        // check if cancellation has been requested previously and reset as required
        if (tokenSource.IsCancellationRequested)
            ResetSourceAndToken();
        Task.Factory.StartNew(() =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.WriteLine("Doing first task");
                Thread.Sleep(1000);
            }
        }, token);
    }
    public void CancelFirstAndRunSecond()
    {
        // Cancel the task that was running
        tokenSource.Cancel();
        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                Console.WriteLine("Doing second task");
                Thread.Sleep(1000);
            }
        });
    }
}

您是否检查cancellationToken ?是否cancelationrequested 在你的代码中?我认为这就是问题所在。

应该是这样的:

// Do function 1
if (token.IsCancellationRequested)
{
    return;
}
// Do function 2
// Were we already canceled?
ct.ThrowIfCancellationRequested();// another variant
// etc

详细信息:https://msdn.microsoft.com/en-us//library/dd997396(v=vs.110).aspx