babalae/better-genshin-impact · error · ArgumentNullException
内部视图模型对象为空
Error message
内部视图模型对象为空
What it means
ArgumentNullException thrown by Dispatcher.RunTask at line 134 when App.GetService<TaskSettingsPageViewModel>() returns null. This is NOT a script-author error — it indicates the WPF DI container has no TaskSettingsPageViewModel registered, or the call happened before the app/DI was built or after disposal. TaskSettingsPageViewModel supplies settings (AutoWood rounds, fight strategy) needed by several task branches.
Source
Thrown at BetterGenshinImpact/Core/Script/Dependence/Dispatcher.cs:134
/// - AutoGeniusInvokation: 启动自动七圣召唤任务
/// - AutoWood: 启动自动伐木任务
/// - AutoFight: 启动自动战斗任务
/// - AutoDomain: 启动自动秘境任务
/// </param>
/// <param name="customCt">自定义取消令牌,允许从JS控制任务取消</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public async Task<object?> RunTask(SoloTask soloTask, CancellationToken? customCt = null)
{
if (soloTask == null)
{
throw new ArgumentNullException(nameof(soloTask), "独立任务对象不能为空");
}
var taskSettingsPageViewModel = App.GetService<TaskSettingsPageViewModel>();
if (taskSettingsPageViewModel == null)
{
throw new ArgumentNullException(nameof(taskSettingsPageViewModel), "内部视图模型对象为空");
}
CancellationToken cancellationToken;
if (customCt != null)
{
cancellationToken = customCt.Value;
}
else
{
// 如果没有自定义令牌,就使用全局令牌
cancellationToken = CancellationContext.Instance.Cts.Token;
}
// 根据名称执行任务
switch (soloTask.Name)
{View on GitHub (pinned to a7cb36712d)
Solutions
- Gate script execution on TaskContext.Instance().IsInitialized (same check PlayMacro uses) before invoking RunTask.
- Ensure TaskSettingsPageViewModel is registered in the DI container at app startup.
- Do not call Dispatcher.RunTask from test/headless contexts; provide a test double or skip.
- If this fires intermittently, delay script start until the main UI is loaded.
Example fix
// before (C# / script host)
dispatcher.RunTask(soloTask); // may throw if DI not ready
// after (C# / script host)
if (!TaskContext.Instance().IsInitialized)
{
throw new InvalidOperationException("Dispatcher.RunTask requires the app to be fully initialized.");
}
dispatcher.RunTask(soloTask); Defensive patterns
Strategy: validation
Validate before calling
// C# host — gate script execution on app readiness
if (!TaskContext.Instance().IsInitialized)
throw new InvalidOperationException("Cannot run tasks before the app is fully initialized."); Prevention
- Do not start scripts until TaskContext.Instance().IsInitialized is true.
- Register TaskSettingsPageViewModel in the DI container at app startup.
- Do not call Dispatcher.RunTask from unit tests without a full DI host.
- Delay script kickoff until the main window/pages are loaded.
When it happens
Trigger: A script runs RunTask before the WPF application finished initializing its service provider. Running the script from a unit test or headless harness that never registered TaskSettingsPageViewModel. The app is shutting down and the DI root has been disposed.
Common situations: Script triggered during early startup (before the main window / pages are constructed). DI registration for pages/viewmodels was removed or moved behind a condition. Integration test reused Dispatcher without spinning up the full app host.
Related errors
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/7d5ff16114aadae3.
Report an issue: GitHub.