feat: TaskQueue 界面 Stop() 也为异步函数,减少 connect 阶段 Stop 的卡顿时间

This commit is contained in:
zzyyyl
2022-09-18 02:31:21 +08:00
parent b96be5fcc2
commit bf9a99f92e
11 changed files with 88 additions and 9 deletions

View File

@@ -62,12 +62,19 @@ bool asst::Assistant::connect(const std::string& adb_path, const std::string& ad
std::unique_lock<std::mutex> lock(m_mutex);
stop(false);
// 仍有任务进行connect 前需要 stop
if (!m_thread_idle) {
return false;
}
m_thread_idle = false;
bool ret = m_ctrler->connect(adb_path, address, config.empty() ? "General" : config);
if (ret) {
m_uuid = m_ctrler->get_uuid();
}
m_thread_idle = true;
return ret;
}

View File

@@ -263,6 +263,9 @@ std::optional<std::string> asst::Controller::call_command(const std::string& cmd
}
while (true) {
if (need_exit()) {
break;
}
wait_handles.clear();
if (process_running) wait_handles.push_back(process_info.hProcess);
if (!pipe_eof) wait_handles.push_back(pipeov.hEvent);
@@ -272,7 +275,7 @@ std::optional<std::string> asst::Controller::call_command(const std::string& cmd
if (wait_handles.empty()) break;
auto elapsed = steady_clock::now() - start_time;
auto wait_time =
(std::min)(timeout - duration_cast<milliseconds>(elapsed).count(), process_running ? 0xFFFFFFFELL : 0LL);
(std::min)(timeout - duration_cast<milliseconds>(elapsed).count(), process_running ? 5LL * 1000 : 0LL);
if (wait_time < 0) break;
auto wait_result =
WaitForMultipleObjectsEx((DWORD)wait_handles.size(), &wait_handles[0], FALSE, (DWORD)wait_time, TRUE);
@@ -440,7 +443,11 @@ std::optional<std::string> asst::Controller::call_command(const std::string& cmd
reconnect_info["details"]["times"] = i;
callback(AsstMsg::ConnectionInfo, reconnect_info);
// TODO: 应该有外部中断 sleep 的写法吧?现在只能在开始或者结束 sleep 的时候判断(
std::this_thread::sleep_for(10s);
if (need_exit()) {
break;
}
auto reconnect_ret = call_command(m_adb.connect, 60LL * 1000, false, false /* 禁止重连避免无限递归 */);
bool is_reconnect_success = false;
if (reconnect_ret) {
@@ -1025,6 +1032,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
});
};
if (need_exit()) {
return false;
}
/* connect */
{
m_adb.connect = cmd_replace(adb_cfg.connect);
@@ -1049,6 +1060,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
}
}
if (need_exit()) {
return false;
}
/* get uuid (imei) */
{
auto uuid_ret = call_command(cmd_replace(adb_cfg.uuid), 20000, false, false /* adb 连接时不允许重试 */);
@@ -1073,6 +1088,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
callback(AsstMsg::ConnectionInfo, info);
}
if (need_exit()) {
return false;
}
// 按需获取display ID 信息
if (!adb_cfg.display_id.empty()) {
auto display_id_ret = call_command(cmd_replace(adb_cfg.display_id));
@@ -1092,6 +1111,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
display_id.pop_back();
}
if (need_exit()) {
return false;
}
/* display */
{
auto display_ret = call_command(cmd_replace(adb_cfg.display));
@@ -1150,6 +1173,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
}
}
if (need_exit()) {
return false;
}
/* calc ratio */
{
constexpr double DefaultRatio =
@@ -1205,6 +1232,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
}
}
if (need_exit()) {
return false;
}
auto socket_opt = try_to_init_socket(bind_address);
if (socket_opt) {
nc_port = socket_opt.value();

View File

@@ -371,6 +371,11 @@ namespace MeoAsstGui
case "Disconnect":
connected = false;
mainModel.AddLog(Localization.GetString("ReconnectFailed"), LogColor.Error);
if (mainModel.Idle)
{
break;
}
AsstStop();
var settingsModel = _container.Get<SettingsViewModel>();
@@ -1002,6 +1007,11 @@ namespace MeoAsstGui
{
foreach (var address in settings.DefaultAddress[settings.ConnectConfig])
{
if (settings.Idle)
{
break;
}
ret = AsstConnect(_handle, settings.AdbPath, address, settings.ConnectConfig);
if (ret)
{

View File

@@ -235,6 +235,7 @@
<system:String x:Key="ConnectingToEmulator">Connecting to emulator...</system:String>
<system:String x:Key="UnselectedTask">Unselected task</system:String>
<system:String x:Key="Running">Running...</system:String>
<system:String x:Key="Stopping">Stopping...</system:String>
<system:String x:Key="Stopped">Has stopped</system:String>
<system:String x:Key="UnknownErrorOccurs">Unknown error occurred</system:String>
<system:String x:Key="SetSuccessfully">Set successfully</system:String>

View File

@@ -235,6 +235,7 @@
<system:String x:Key="ConnectingToEmulator">エミュレータ接続中……</system:String>
<system:String x:Key="UnselectedTask">タスクが選択されていません</system:String>
<system:String x:Key="Running">動作中……</system:String>
<system:String x:Key="Stopping">動作停止中……</system:String><!-- need help -->
<system:String x:Key="Stopped">動作停止</system:String>
<system:String x:Key="UnknownErrorOccurs">不明なエラーが発生しました</system:String>
<system:String x:Key="SetSuccessfully">設定に成功しました</system:String>

View File

@@ -234,7 +234,8 @@
<system:String x:Key="ConnectingToEmulator">에뮬레이터에 연결중...</system:String>
<system:String x:Key="UnselectedTask">선택된 작업이 없다</system:String>
<system:String x:Key="Running">실행중...</system:String>
<system:String x:Key="Stopped">정지됐다</system:String>
<system:String x:Key="Stopping">멎는...</system:String>
<system:String x:Key="Stopped">멈췄다</system:String>
<system:String x:Key="UnknownErrorOccurs">예상치 못한 오류가 발생했습니다</system:String>
<system:String x:Key="SetSuccessfully">설정 성공</system:String>
<system:String x:Key="SetFailed">설정 실패</system:String>

View File

@@ -234,6 +234,7 @@
<system:String x:Key="ConnectingToEmulator">🍸🕺🍻💃🕺</system:String>
<system:String x:Key="UnselectedTask">🍺🍸🍻</system:String>
<system:String x:Key="Running">🍷🍻🍷🍺</system:String>
<system:String x:Key="Stopping">🍷💃🍸</system:String>
<system:String x:Key="Stopped">💃🍺</system:String>
<system:String x:Key="UnknownErrorOccurs">🕺🍸🍻🍷</system:String>
<system:String x:Key="SetSuccessfully">🍸🍸🍺</system:String>

View File

@@ -235,6 +235,7 @@
<system:String x:Key="ConnectingToEmulator">正在连接模拟器……</system:String>
<system:String x:Key="UnselectedTask">未选择任务</system:String>
<system:String x:Key="Running">正在运行中……</system:String>
<system:String x:Key="Stopping">正在停止……</system:String>
<system:String x:Key="Stopped">已停止</system:String>
<system:String x:Key="UnknownErrorOccurs">出现未知错误</system:String>
<system:String x:Key="SetSuccessfully">设置成功</system:String>

View File

@@ -235,6 +235,7 @@
<system:String x:Key="ConnectingToEmulator">正在連接模擬器……</system:String>
<system:String x:Key="UnselectedTask">未選擇任務</system:String>
<system:String x:Key="Running">正在運行中……</system:String>
<system:String x:Key="Stopping">正在停止……</system:String>
<system:String x:Key="Stopped">已停止</system:String>
<system:String x:Key="UnknownErrorOccurs">出現未知錯誤</system:String>
<system:String x:Key="SetSuccessfully">設定成功</system:String>

View File

@@ -624,6 +624,13 @@ namespace MeoAsstGui
return asstProxy.AsstConnect(ref errMsg, true);
});
bool caught = await task;
// 一般是点了“停止”按钮了
if (Idle)
{
return;
}
if (!caught)
{
AddLog(errMsg, LogColor.Error);
@@ -732,12 +739,18 @@ namespace MeoAsstGui
/// <summary>
/// Stops.
/// </summary>
public void Stop()
public async void Stop()
{
var asstProxy = _container.Get<AsstProxy>();
asstProxy.AsstStop();
Idle = true; // 提前将 Idle 置为 true
Stopping = true;
AddLog(Localization.GetString("Stopping"));
var task = Task.Run(() =>
{
return _container.Get<AsstProxy>().AsstStop();
});
await task;
AddLog(Localization.GetString("Stopped"));
Idle = true;
Stopping = false;
}
private bool appendStart()
@@ -1254,6 +1267,17 @@ namespace MeoAsstGui
}
}
private bool _stopping = false;
/// <summary>
/// Gets or sets a value indicating whether `stop` is awaiting.
/// </summary>
public bool Stopping
{
get => _stopping;
set => SetAndNotify(ref _stopping, value);
}
private bool _fightTaskRunning = false;
/// <summary>

View File

@@ -140,14 +140,15 @@
Command="{s:Action LinkStart}"
Content="{DynamicResource LinkStart}"
IsEnabled="{Binding Inited}"
Visibility="{c:Binding Path='Idle or !Inited'}" />
Visibility="{c:Binding Path='(Idle and !Stopping) or !Inited'}" />
<Button
Width="100"
Height="50"
Margin="5"
Command="{s:Action Stop}"
Content="{DynamicResource Stop}"
Visibility="{c:Binding Path='!Idle and Inited'}" />
IsEnabled="{c:Binding Path='!Stopping'}"
Visibility="{c:Binding Path='(!Idle or Stopping) and Inited'}" />
</Grid>
<!--<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment ="Center" >-->