取消在用户控制下运行的任务

时间:2019-04-04 10:51:13

标签: c# task

在我的项目中,通过导航更改的用户控件很少。控件之一运行任务。我是这样的:

public partial class uc_WorkingArea : UserControl
{
    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken token;

    public uc_WorkingArea()
        {
            InitializeComponent();
            this.Unloaded += uc_WorkingArea_Unloaded;
            token = cts.Token;
            Task Printer1 = Task.Run(() => PrinterPooler(lst_PrinterStruct, 0), cts.Token);
        }


         private void uc_WorkingArea_Unloaded(object sender, RoutedEventArgs e)
        {
            cts.Cancel();
            if (token.CanBeCanceled)
            {
                MessageBox.Show("Can be canceled");
            }

            if (token.IsCancellationRequested)
            {
                MessageBox.Show("Canceled requested");
            }
            cts.Cancel();
            MessageBox.Show("Status: " + Printer1.Status.ToString());
        }
}

当我离开当前的用户控件并切换到另一个uc_WorkingArea_Unloaded时,将执行。我看到消息,可以取消任务并接受取消请求。

但是,Printer1任务的当前状态仍为“ IsRunning”。 因此,如果我返回到该用户控件,则Task将再次启动,并且Application具有两个正在运行的相似任务。

我试过像这样在Factory下运行任务

Task Printer1 = Task.Factory.StartNew(() => PrinterPooler(lst_PrinterStruct, 0), cts.Token);

但是没有成功。 App仍然运行两个类似的任务。

PrinterPooler方法不同步。

我不明白哪里犯了错误。需要您的帮助。

2 个答案:

答案 0 :(得分:1)

您必须将令牌传递到PrintPooler方法中,然后在内部检查是否应取消令牌。

for(int i = 0; i < 10000; i++)
{
   DoStuff();
   cancelToken.ThrowIfCancellationRequested(); // if tasks end with this exception, it knows the work has been cancelled
}

取消任务不会停止执行,它只是向内部代码发出信号,表明应该结束,并根据执行停止的方式将任务状态设置为Cancelled / Faulted / RanToCompletion。

请注意,您需要将相同的令牌传递给Task和将其抛出的方法。

答案 1 :(得分:1)

关于此帖子How do I abort/cancel TPL Tasks?

您必须自己实现烛光状态。例如:

public partial class uc_WorkingArea : UserControl
{
    public CancellationTokenSource cts = new CancellationTokenSource();
    public CancellationToken token;
    public Task Printer1;

    public uc_WorkingArea()
    {
        token = cts.Token;
        Printer1 = Task.Factory.StartNew(() =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.WriteLine("run");
                Application.DoEvents();
            }
        }, token);
    }
}

取消通话:

    uc_WorkingArea gc = new uc_WorkingArea();

    for (int i = 0; i < 10; i++) //PASS SOME TIME
    {
        Application.DoEvents(); //CONSOLE SHOULD SPAM 'RUN' FROM TASK
        Thread.Sleep(1);
    }

    gc.cts.Cancel(); //CANCEL CALL, WHILE LOOP END
    if (gc.token.IsCancellationRequested)
    {
        Console.WriteLine("stop");
        MessageBox.Show("Canceled requested");

    }
    gc.cts.Dispose();
    gc.Printer1.Dispose();

希望有帮助。

相关问题