diff --git a/src/MaaWpfGui/Services/StageManager.cs b/src/MaaWpfGui/Services/StageManager.cs
index b195236651..e739a52359 100644
--- a/src/MaaWpfGui/Services/StageManager.cs
+++ b/src/MaaWpfGui/Services/StageManager.cs
@@ -32,6 +32,7 @@ using StyletIoC;
namespace MaaWpfGui.Services
{
+
///
/// Stage manager
///
@@ -40,6 +41,9 @@ namespace MaaWpfGui.Services
[DllImport("MaaCore.dll")]
private static extern IntPtr AsstGetVersion();
+ private const string StageApi = "gui/StageActivity.json";
+ private const string TasksApi = "resource/tasks.json";
+
// model references
private readonly TaskQueueViewModel _taskQueueViewModel;
private readonly IMaaApiService _maaApiService;
@@ -57,49 +61,38 @@ namespace MaaWpfGui.Services
{
_taskQueueViewModel = container.Get();
_maaApiService = container.Get();
- UpdateStage(false);
+ UpdateStageLocal();
- Execute.OnUIThread(async () =>
+ Task.Run(async () =>
{
- var task = Task.Run(() =>
- {
- UpdateStage(true);
- });
- await task;
+ await UpdateStageWeb();
if (_taskQueueViewModel != null)
{
- _taskQueueViewModel.UpdateDatePrompt();
- _taskQueueViewModel.UpdateStageList(true);
+ Execute.OnUIThread(() =>
+ {
+ _taskQueueViewModel.UpdateDatePrompt();
+ _taskQueueViewModel.UpdateStageList(true);
+ });
}
});
}
- public void UpdateStage(bool fromWeb)
+ public void UpdateStageLocal()
{
- if (fromWeb)
+ UpdateStageInternal(LoadLocalStages());
+ }
+
+ public async Task UpdateStageWeb()
+ {
+ if (await CheckWebUpdate())
{
- // Check if we need to update from the web
- string lastUpdateTimeFile = "lastUpdateTime.json";
- JObject localLastUpdatedJson = _maaApiService.LoadApiCache(lastUpdateTimeFile);
- JObject webLastUpdatedJson = _maaApiService.RequestMaaApiWithCache(lastUpdateTimeFile).ConfigureAwait(false).GetAwaiter().GetResult();
- if (localLastUpdatedJson != null && webLastUpdatedJson != null)
- {
- long localTimestamp = localLastUpdatedJson["timestamp"].ToObject();
- long webTimestamp = webLastUpdatedJson["timestamp"].ToObject();
- if (webTimestamp <= localTimestamp)
- {
- return;
- }
- }
+ UpdateStageInternal(await LoadWebStages());
+ return;
}
+ }
- var tempStage = new Dictionary
- {
- // 这里会被 “剩余理智” 复用,第一个必须是 string.Empty 的
- // 「当前/上次」关卡导航
- { string.Empty, new StageInfo { Display = LocalizationHelper.GetString("DefaultStage"), Value = string.Empty } },
- };
-
+ private string GetClientType()
+ {
var clientType = ConfigurationHelper.GetValue(ConfigurationKeys.ClientType, string.Empty);
// 官服和B服使用同样的资源
@@ -108,28 +101,66 @@ namespace MaaWpfGui.Services
clientType = "Official";
}
- // Download the activities
- const string StageApi = "gui/StageActivity.json";
- JObject activity = fromWeb
- ? _maaApiService.RequestMaaApiWithCache(StageApi).ConfigureAwait(false).GetAwaiter().GetResult()
- : _maaApiService.LoadApiCache(StageApi);
+ return clientType;
+ }
- // Download the tasks resources into cache so MaaCore can load them later
- var tasksPath = "resource/tasks.json";
- JObject tasksJson = fromWeb
- ? _maaApiService.RequestMaaApiWithCache(tasksPath).ConfigureAwait(false).GetAwaiter().GetResult()
- : _maaApiService.LoadApiCache(tasksPath);
+ private JObject LoadLocalStages()
+ {
+ JObject activity = _maaApiService.LoadApiCache(StageApi);
+ JObject tasksJson = _maaApiService.LoadApiCache(TasksApi);
+ return activity;
+ }
+
+ private async Task CheckWebUpdate()
+ {
+ // Check if we need to update from the web
+ string lastUpdateTimeFile = "lastUpdateTime.json";
+ JObject localLastUpdatedJson = _maaApiService.LoadApiCache(lastUpdateTimeFile);
+ JObject webLastUpdatedJson = await _maaApiService.RequestMaaApiWithCache(lastUpdateTimeFile).ConfigureAwait(false);
+ if (localLastUpdatedJson != null && webLastUpdatedJson != null)
+ {
+ long localTimestamp = localLastUpdatedJson["timestamp"].ToObject();
+ long webTimestamp = webLastUpdatedJson["timestamp"].ToObject();
+ if (webTimestamp <= localTimestamp)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private async Task LoadWebStages()
+ {
+ var clientType = GetClientType();
+
+ JObject activity = await _maaApiService.RequestMaaApiWithCache(StageApi);
+ JObject tasksJson = await _maaApiService.RequestMaaApiWithCache(TasksApi);
if (clientType != "Official" && tasksJson != null)
{
- tasksPath = "resource/global/" + clientType + '/' + tasksPath;
+ var tasksPath = "resource/global/" + clientType + '/' + TasksApi;
// Download the client specific resources only when the Official ones are successfully downloaded so that the client specific resource version is the actual version
// TODO: There may be an issue when the CN resource is loaded from cache (e.g. network down) while global resource is downloaded (e.g. network up again)
// var tasksJsonClient = fromWeb ? WebService.RequestMaaApiWithCache(tasksPath) : WebService.RequestMaaApiWithCache(tasksPath);
- _ = _maaApiService.RequestMaaApiWithCache(tasksPath);
+ await _maaApiService.RequestMaaApiWithCache(tasksPath);
}
+ return activity;
+ }
+
+ private void UpdateStageInternal(JObject activity)
+ {
+ var tempStage = new Dictionary
+ {
+ // 这里会被 “剩余理智” 复用,第一个必须是 string.Empty 的
+ // 「当前/上次」关卡导航
+ { string.Empty, new StageInfo { Display = LocalizationHelper.GetString("DefaultStage"), Value = string.Empty } },
+ };
+
+ var clientType = GetClientType();
+
bool isDebugVersion = Marshal.PtrToStringAnsi(AsstGetVersion()) == "DEBUG VERSION";
bool curVerParsed = SemVersion.TryParse(Marshal.PtrToStringAnsi(AsstGetVersion()), SemVersionStyles.AllowLowerV, out var curVersionObj);
diff --git a/src/MaaWpfGui/Services/Web/HttpService.cs b/src/MaaWpfGui/Services/Web/HttpService.cs
index e84ff016f6..9a6531d472 100644
--- a/src/MaaWpfGui/Services/Web/HttpService.cs
+++ b/src/MaaWpfGui/Services/Web/HttpService.cs
@@ -1,4 +1,4 @@
-//
+//
// MaaWpfGui - A part of the MaaCoreArknights project
// Copyright (C) 2021 MistEO and Contributors
//
@@ -163,7 +163,7 @@ namespace MaaWpfGui.Services.Web
var success = true;
try
{
- var stream = response.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult();
+ var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using var fileStream = new FileStream(fullFilePathWithTemp, FileMode.Create, FileAccess.Write);
// 记录初始化
diff --git a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs
index 2c874d6c83..ae69001584 100644
--- a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs
+++ b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs
@@ -1749,14 +1749,10 @@ namespace MaaWpfGui.ViewModels.UI
///
/// Updates manually.
///
- // TODO: 你确定要用 async void 不是 async Task?
- public async void ManualUpdate()
+ /// A representing the asynchronous operation.
+ public async Task ManualUpdate()
{
- var task = Task.Run(() =>
- {
- return _versionUpdateViewModel.CheckAndDownloadUpdate(true);
- });
- var ret = await task;
+ var ret = await _versionUpdateViewModel.CheckAndDownloadUpdate(true);
string toastMessage = null;
switch (ret)
diff --git a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs
index 146720a62a..c8bee3681c 100644
--- a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs
+++ b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs
@@ -22,7 +22,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
-using System.Windows.Forms;
+using System.Windows.Threading;
using MaaWpfGui.Constants;
using MaaWpfGui.Extensions;
using MaaWpfGui.Helper;
@@ -171,12 +171,11 @@ namespace MaaWpfGui.ViewModels.UI
}
*/
- private readonly Timer _timer = new Timer();
+ private readonly DispatcherTimer _timer = new DispatcherTimer();
private void InitTimer()
{
- _timer.Enabled = true;
- _timer.Interval = 1000 * 50;
+ _timer.Interval = TimeSpan.FromSeconds(50);
_timer.Tick += Timer1_Elapsed;
_timer.Start();
}
@@ -185,11 +184,14 @@ namespace MaaWpfGui.ViewModels.UI
{
if (NeedToUpdateDatePrompt())
{
- Execute.OnUIThread(() =>
+ Task.Run(async () =>
{
- _stageManager.UpdateStage(true);
- UpdateDatePrompt();
- UpdateStageList(false);
+ await _stageManager.UpdateStageWeb();
+ Execute.OnUIThread(() =>
+ {
+ UpdateDatePrompt();
+ UpdateStageList(false);
+ });
});
}
@@ -204,7 +206,7 @@ namespace MaaWpfGui.ViewModels.UI
{
if (_settingsViewModel.UpdatAutoCheck)
{
- _settingsViewModel.ManualUpdate();
+ Task.Run(_settingsViewModel.ManualUpdate);
}
}
diff --git a/src/MaaWpfGui/ViewModels/UI/VersionUpdateViewModel.cs b/src/MaaWpfGui/ViewModels/UI/VersionUpdateViewModel.cs
index 90902a5ad4..be09a1dfa0 100644
--- a/src/MaaWpfGui/ViewModels/UI/VersionUpdateViewModel.cs
+++ b/src/MaaWpfGui/ViewModels/UI/VersionUpdateViewModel.cs
@@ -20,6 +20,7 @@ using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
@@ -357,14 +358,13 @@ namespace MaaWpfGui.ViewModels.UI
///
/// 是否强制检查。
/// 操作成功返回 ,反之则返回 。
- public CheckUpdateRetT CheckAndDownloadUpdate(bool force = false)
+ public async Task CheckAndDownloadUpdate(bool force = false)
{
_settingsViewModel.IsCheckingForUpdates = true;
- var checkResult = ((Func)(() =>
- {
+ async Task CheckUpdateInner() {
// 检查更新
- var checkRet = CheckUpdate(force);
+ var checkRet = await CheckUpdate(force);
if (checkRet != CheckUpdateRetT.OK)
{
return checkRet;
@@ -507,7 +507,9 @@ namespace MaaWpfGui.ViewModels.UI
}
return CheckUpdateRetT.OK;
- }))();
+ }
+
+ var checkResult = await CheckUpdateInner();
_settingsViewModel.IsCheckingForUpdates = false;
return checkResult;
@@ -537,7 +539,7 @@ namespace MaaWpfGui.ViewModels.UI
///
/// 是否强制检查。
/// 检查到更新返回 ,反之则返回 。
- private CheckUpdateRetT CheckUpdate(bool force = false)
+ private async Task CheckUpdate(bool force = false)
{
// 自动更新或者手动触发
if (!(_settingsViewModel.UpdateCheck || force))
@@ -558,7 +560,7 @@ namespace MaaWpfGui.ViewModels.UI
{
// 稳定版更新使用主仓库 /latest 接口
// 直接使用 MaaRelease 的话,30 个可能会找不到稳定版,因为有可能 Nightly 发了很多
- var stableResponse = RequestGithubApi(StableRequestUrl, RequestRetryMaxTimes);
+ var stableResponse = await RequestGithubApi(StableRequestUrl, RequestRetryMaxTimes);
if (string.IsNullOrEmpty(stableResponse))
{
return CheckUpdateRetT.NetworkError;
@@ -566,7 +568,7 @@ namespace MaaWpfGui.ViewModels.UI
_latestJson = JsonConvert.DeserializeObject(stableResponse) as JObject;
_latestVersion = _latestJson["tag_name"].ToString();
- stableResponse = RequestGithubApi(MaaReleaseRequestUrlByTag + _latestVersion, RequestRetryMaxTimes);
+ stableResponse = await RequestGithubApi(MaaReleaseRequestUrlByTag + _latestVersion, RequestRetryMaxTimes);
// 主仓库能找到版,但是 MaaRelease 找不到,说明 MaaRelease 还没有同步(一般过个十分钟就同步好了)
if (string.IsNullOrEmpty(stableResponse))
@@ -579,7 +581,7 @@ namespace MaaWpfGui.ViewModels.UI
else
{
// 非稳定版更新使用 MaaRelease/releases 接口
- var response = RequestGithubApi(RequestUrl, RequestRetryMaxTimes);
+ var response = await RequestGithubApi(RequestUrl, RequestRetryMaxTimes);
if (string.IsNullOrEmpty(response))
{
return CheckUpdateRetT.NetworkError;
@@ -636,7 +638,7 @@ namespace MaaWpfGui.ViewModels.UI
// 非稳定版本是 Nightly 下载的,主仓库没有它的更新信息,不必请求
if (isStdVersion(_latestVersion))
{
- var infoResponse = RequestGithubApi(InfoRequestUrl + _latestVersion, RequestRetryMaxTimes);
+ var infoResponse = await RequestGithubApi(InfoRequestUrl + _latestVersion, RequestRetryMaxTimes);
if (string.IsNullOrEmpty(infoResponse))
{
return CheckUpdateRetT.FailedToGetInfo;
@@ -672,7 +674,7 @@ namespace MaaWpfGui.ViewModels.UI
}
}
- private string RequestGithubApi(string url, int retryTimes)
+ private async Task RequestGithubApi(string url, int retryTimes)
{
string response = string.Empty;
string[] requestSource = { "https://api.github.com/", "https://api.kgithub.com/" };
@@ -680,7 +682,8 @@ namespace MaaWpfGui.ViewModels.UI
{
for (var i = 0; i < requestSource.Length; i++)
{
- response = _httpService.GetStringAsync(new Uri(requestSource[i] + url)).ConfigureAwait(false).GetAwaiter().GetResult();
+ // prevent current thread
+ response = await _httpService.GetStringAsync(new Uri(requestSource[i] + url)).ConfigureAwait(false);
if (!string.IsNullOrEmpty(response))
{
break;