停止长嵌套循环任务

时间:2016-07-08 10:03:53

标签: c# task multitasking cancellation-token

当用户点击转义键时,我需要停止运行任务。问题是任务正在运行如下方法:

void Start(){

    while(long loop){
        while(!userEvent) System.Windows.Forms.Application.DoEvents();
        for(another long loop){
             while(more loops)
        }
    }
}

我所学习的所有浏览论坛的主题都是使用CancellationToken你需要像这样处理它:

if (token.IsCancellationRequested)
{
        // Clean up here, then...
        "cleanup".Dump();
        token.ThrowIfCancellationRequested();
}

由于循环太多,检查是否请求取消将非常低效且难以阅读。

任务需要在读取内部事件的窗口时停止,所以我不能在下一次迭代之前检查CancellationToken,它几乎无处不在

那么,有没有办法在任何循环中停止任务? 它不需要与CancellationTokens一起使用,但它似乎是这种方式的“标准”方式。

此外,方法Start()最初没有被用作任务,但是这样就可以使得即使在关闭窗口之后主线程仍然运行代码,除非我使用了一堆if (windowClosed) break同样不切实际。

2 个答案:

答案 0 :(得分:2)

只要有多少循环,异常就会传播。

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Escape:
            cancallation.Cancel();
            break;
    }
}

private CancellationTokenSource cancallation = new CancellationTokenSource();

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
        while (...)
        {
            for (...)
            {
                cancallation.Token.ThrowIfCancellationRequested();
            }
        }
    }, cancallation.Token);
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    if (cancallation.IsCancellationRequested == false)
    {
        cancallation.Cancel();
    }
}

答案 1 :(得分:1)

这是goto语句的用例(请参阅https://msdn.microsoft.com/en-us/library/13940fs2.aspx)。

    void nestedExit()
    {
        while (true)
        {
            while (true)
            {
                while (true)
                {
                    while (true)
                    {
                        while (true)
                        {
                            goto Done;
                        }
                    }
                }
            }
        }

    Done:
        ;
    }

注意:分号是使该行成为语句所必需的。只是标签和右括号不能编译。