加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 为什么PauseToken会破坏任务?

发布时间:2020-12-15 23:41:37 所属栏目:百科 来源:网络整理
导读:我正在尝试了解Microsoft.VisualStudio.Workspace.PauseToken. 当我调用PauseTokenSource.Pause()时,方法暂停并且任务完成,我可以看到“已完成”消息. 之后我调用了PauseTokenSource.Resume(),然后继续执行任务. 但是当流程结束时我没有任何消息. 两个问题:
我正在尝试了解Microsoft.VisualStudio.Workspace.PauseToken.

当我调用PauseTokenSource.Pause()时,方法暂停并且任务完成,我可以看到“已完成”消息.

之后我调用了PauseTokenSource.Resume(),然后继续执行任务.
但是当流程结束时我没有任何消息.

两个问题:

>为什么会这样?
>我该如何解决?

我希望PauseToken在工作期间不会破坏任务.暂停后我不想收到消息.我希望在流程的真正结束时收到消息.

public PauseToken PauseToken;

private async Task DoDoneAsync()
{
    FlagCommandDone = true;

    try
    {
        task = Task.Factory.StartNew(async () =>
            {
                double i = 0;
                while (i < 3)
                {
                    i++;
                    await PauseToken.WaitWhilePausedAsync();
                    Thread.Sleep(5000);
                }
            }
        );
        await task;
    }
    catch (Exception e)
    {
        isError = true;
        message = e.Message;
    }

    if (!isError) message = task.IsCompleted ? "Completed" : "Canceled";

    MessageBox.Show(message);

    FlagCommandDone = false;
}

编辑:

task = Task.Factory.StartNew(async () =>
{
    double i = 0;
    while (i < 3)
    {
        i++;
        CurrentStatus = i.ToString();
        var a = (int)(double)((i / 3.0) * 100.0);
        MessageBox.Show(PauseToken.IsPaused.ToString());
        await PauseToken.WaitWhilePausedAsync();
        CancellationToken.ThrowIfCancellationRequested();
        Thread.Sleep(5000);
        CurrentProgress = a;
    }
},CancellationToken);

解决方法

代码的问题在于,当被调用的方法返回时,StartNew()创建的任务被认为是完整的.当然,它是await的异步方法,只要在不完整的任务上执行第一个await,该方法就会返回.

所以,你的DoDoneAsync()方法实际上是在你认为你开始完成之前完成的.它本质上只等待你的StartNew()方法到达它的第一个await.

如果没有一个可靠地再现您的问题的好的Minimal,Complete,and Verifiable code example,就不可能确定什么会修复您的程序.但是,我认为最重要的是停止尝试将阻止代码与异步代码混合使用.相反,只需将StartNew()调用的匿名方法分解为自己的命名方法,使其正确异步,并直接调用它.

例如:

private async Task DoDoneAsync()
{
    FlagCommandDone = true;

    try
    {
        await DoDoneLoopAsync();
    }
    catch (Exception e)
    {
        isError = true;
        message = e.Message;
    }

    if (!isError) message = task.IsCompleted ? "Completed" : "Canceled";

    MessageBox.Show(message);

    FlagCommandDone = false;
}

private async Task DoDoneLoopAsync()
{
    double i = 0;
    while (i < 3)
    {
        i++;
        await PauseToken.WaitWhilePausedAsync();
        await Task.Delay(5000);
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读