Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] 暂停后再继续引发System.ArgumentNullException异常 #1096

Closed
1 task done
iamscottxu opened this issue Sep 17, 2024 · 1 comment
Closed
1 task done

[Bug] 暂停后再继续引发System.ArgumentNullException异常 #1096

iamscottxu opened this issue Sep 17, 2024 · 1 comment
Labels
triage Issue needs to be triaged

Comments

@iamscottxu
Copy link
Contributor

iamscottxu commented Sep 17, 2024

Checklist

  • My issue was not mentioned by others, and it is not a duplicate issue.

Description

疑似 #1019 合入的代码导致。@Eric-Joker 想询问下这样写的原因是否和我理解的一样,讨论下看看有什么修复方案。
暂停继续逻辑问题,以下代码,依照我的理解,实际上是想解决暂停后马上继续会造成上一次任务未结束,下一次任务就开始了的问题。不过没有修改完整,导致启动任务时未设置TaskItems变量的值,导致空引用异常。
InstallGameStateModel.cs:

private void ContinueOrPause()
    {
        if (ButtonGlyph is PlayGlyph)
        {
            Task.Run(() =>
            {
                Task.WhenAll(Service.TaskItems).Wait(); //System.ArgumentNullException: Value cannot be null. (Parameter 'tasks')
                Service.Continue();
                InstallStarted?.Invoke(this, EventArgs.Empty);
            });
        }
        else if (ButtonGlyph is PauseGlyph)
        {
            Service.Pause();
        }
    }

此问题我建议弃用这种方案,因为这个问题涉及到取消时可能需要清理资源需要一定的时间,这个问题不仅在暂停时存在,取消下载和关闭程序时同样存在,上述方案虽然从使用者体验上来说,暂停速度很快,但是无法解决取消后立即重新开始下载时上一个下载任务可能还在清理资源的问题,也无法解决资源未清理完成程序就已经退出的问题。根据大部分软件的通行做法,应该添加”正在暂停/正在取消“的状态来修复更为妥当。
因为流式下载使用了更多的线程,且有更多的资源清理操作,暂停时间变长,快速“暂停/继续”和“取消/重新下载”大概率导致任务重复运行,出现行为异常,”正在暂停/正在取消“状态已经在 #1037 实现,并且 #1037 中已经提交代码修复上述问题,如果需要我可以单独提一个pr。

Reproduction Steps

  1. 打开程序,点击下载游戏;
  2. 点击暂停按钮暂停下载;
  3. 点击继续按钮恢复下载;
  4. 引发空引用异常。

Expected Behavior

点击继续按钮后不引发异常,继续完成未完成的下载任务。

Screenshots

image

Starward Version

main分支:93c028d

Windows Version

复现时系统版本:26100.1742(与操作系统版本无关)

Log

System.ArgumentNullException: Value cannot be null. (Parameter 'tasks')
   at System.Threading.Tasks.Task.WhenAll(IEnumerable`1 tasks)
   at Starward.Services.Download.InstallGameStateModel.<ContinueOrPause>b__42_0() in InstallGameStateModel.cs:line 112
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)

Additional Context

No response

@iamscottxu iamscottxu added the triage Issue needs to be triaged label Sep 17, 2024
@Eric-Joker
Copy link
Contributor

Eric-Joker commented Sep 17, 2024

异常是因为合并#1019删除了为TaskItems赋值的代码导致的。

目前还未实现流式解压所以我那简单的处理足以应付,因为释放资源的时长很短。将来实现后必然需要更好的处理方案。

修复方案择一,需要来个人 @Scighost 拍板():

  • 作者加速审查#1037顶替现有逻辑

  • 大佬单独把#1037里的相关逻辑提个PR

  • 恢复赋值:

    1. InstallGameService.cs#L628-L629改为
    protected Task[] _taskItems;
    public Task[] TaskItems => _taskItems;
    1. L729-L736改为
    _taskItems = new Task[Environment.ProcessorCount];
    for (int i = 0; i < Environment.ProcessorCount; i++)
    {
        _taskItems[i] = ExecuteTaskItemAsync(_cancellationTokenSource.Token);
    }
    try
    {
        await Task.WhenAll(_taskItems).ConfigureAwait(false);
  • 彻底删除此逻辑的代码:

    1. 删除InstallGameService.cs#L627-L632
    2. InstallGameStateModel.cs#L110-L115改为
    Service.Continue();
    InstallStarted?.Invoke(this, EventArgs.Empty);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage Issue needs to be triaged
Projects
None yet
Development

No branches or pull requests

2 participants