Skip to content

Commit

Permalink
fix stop task issue
Browse files Browse the repository at this point in the history
  • Loading branch information
butaixianran committed Dec 15, 2023
1 parent a990793 commit 3f147dc
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 123 deletions.
215 changes: 95 additions & 120 deletions N_m3u8DL-CLI-SimpleG/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public partial class MainWindow : System.Windows.Window
//下载进程
private Process m3u8dlProcess;
private TaskCompletionSource<bool> m3u8dlEventHandled;
//下载时,读取后台下载进程的log到UI用
StreamReader logBlockReader;

public MainWindow()
{
Expand Down Expand Up @@ -1261,20 +1263,29 @@ private async Task StartDownloadProcessAsync(string fileName, string arguments)
m3u8dlProcess.Exited += new EventHandler(DownloadProcess_Exited);
m3u8dlProcess.Start(); //启动

}
catch (Exception e)
{
MessageBox.Show($"调用下载进程出错:{e.Message}");
return;
}

// 等待后台进程Log
try
{
//获取输出
StreamReader reader = m3u8dlProcess.StandardOutput;
logBlockReader = m3u8dlProcess.StandardOutput;
// 每次读取一行
string line = "";
while (!reader.EndOfStream)
while (logBlockReader != null && !logBlockReader.EndOfStream)
{
line = await reader.ReadLineAsync();
line = await logBlockReader.ReadLineAsync();
WriteLogBlockLine(line);
}

}
catch (Exception e)
{
MessageBox.Show($"调用下载进程出错:{e.Message}");
MessageBox.Show($"读取后台下载进程Log出错:{e.Message}");
return;
}

Expand Down Expand Up @@ -1307,7 +1318,7 @@ private void DownloadProcess_Exited(object sender, System.EventArgs e)
}
catch (Exception ex)
{
MessageBox.Show($"设置进程完成出错:{ex.Message}");
MessageBox.Show($"设置下载进程为完成时出错:{ex.Message}");
return;
}

Expand Down Expand Up @@ -1350,138 +1361,67 @@ private M3u8TaskItem GetNextTaskToDownload()
/// <param name="e"></param>
private async void TaskStartAsync_Click(object sender, RoutedEventArgs e)
{
try
{
//定义要下载的任务
M3u8TaskItem item = GetNextTaskToDownload();

//在下载期间,用户可能继续添加任务到列表,所以列表长度是动态变化的
//因此,不能简单用foreach遍历列表,会报错:集合已修改 可能无法执行枚举操作
//解决办法是,单独遍历任务列表,获取要下载的任务。
//再把下载放在while循环中,然后每完成一个任务,都重新检查列表,判断是否需要继续
while (item != null)
{
//检查任务列表状态
if (this.tasks_status == "stopped")
{
//重置状态并退出运行
this.tasks_status = "";
break;
}

//清理LogBlock
ClearLogBlock();

//修改任务状态
item.Status = "Downloading";
lbTaskList.Items.Refresh();

//启动异步下载
try
{
await StartDownloadProcessAsync(TextBox_EXE.Text, item.Parameter);
}
catch (Exception ex)
{
MessageBox.Show($"运行异步下载出错:{ex.Message}");
return;
}


try
{
//再次修改任务状态
item.Status = "Done";
lbTaskList.Items.Refresh();
}
catch (Exception ex)
{
MessageBox.Show($"修改任务状态出错:{ex.Message}");
return;
}

//获取下一个任务
item = GetNextTaskToDownload();
}



}
catch (Exception ex)
{
MessageBox.Show($"下载过程出错:{ex.Message}");
return;
}
//重置任务列表状态
this.tasks_status = "";

}
//定义要下载的任务
M3u8TaskItem item = GetNextTaskToDownload();

/// <summary>
/// 启动任务列表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TaskStart_Click(object sender, RoutedEventArgs e)
{
//遍历任务列表,查找下一个需要下载的任务
foreach(M3u8TaskItem item in this.m3u8_tasks)
//在下载期间,用户可能继续添加任务到列表,所以列表长度是动态变化的
//因此,不能简单用foreach遍历列表,会报错:集合已修改 可能无法执行枚举操作
//解决办法是,单独遍历任务列表,获取要下载的任务。
//再把下载放在while循环中,然后每完成一个任务,都重新检查列表,判断是否需要继续
while (item != null)
{
//检查任务列表状态
if (this.tasks_status == "stopped")
if (this.tasks_status == "stopped")
{
//重置状态并退出运行
this.tasks_status = "";
break;
}

//检查当前遍历到的任务状态
if (string.IsNullOrEmpty(item.Status))
//清理LogBlock
ClearLogBlock();

//修改任务状态
item.Status = "Downloading";
lbTaskList.Items.Refresh();

//启动异步下载
try
{
//检查参数
if (string.IsNullOrEmpty(item.Parameter))
{
item.Status = "Empty Parameter";
continue;
}
else
{
//修改任务状态
item.Status = "Downloading";
lbTaskList.Items.Refresh();
await StartDownloadProcessAsync(TextBox_EXE.Text, item.Parameter);
}
catch (Exception ex)
{
MessageBox.Show($"运行异步下载出错:{ex.Message}");
return;
}

//启动下载工具
using (Process p = Process.Start(TextBox_EXE.Text, item.Parameter))
{
p.WaitForExit();//等待程序执行完退出进程
p.Close();
}

//using (Process p = new Process())
//{
// p.StartInfo.FileName = TextBox_EXE.Text;
// p.StartInfo.UseShellExecute = true; //是否使用操作系统shell启动
// p.StartInfo.RedirectStandardInput = true; //接受来自调用程序的输入信息
// //p.StartInfo.RedirectStandardOutput = true; //由调用程序获取输出信息
// //p.StartInfo.RedirectStandardError = true; //重定向标准错误输出
// p.StartInfo.CreateNoWindow = false; //不显示程序窗口
// p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
// p.Start();//启动程序
// p.StandardInput.AutoFlush = true;

// p.WaitForExit();//等待程序执行完退出进程
// p.Close();
//}

//再次修改任务状态
try
{
//再次修改任务状态
if (item.Status == "Downloading")
{
item.Status = "Done";
lbTaskList.Items.Refresh();

}

}
catch (Exception ex)
{
MessageBox.Show($"修改任务状态出错:{ex.Message}");
return;
}

//获取下一个任务
item = GetNextTaskToDownload();
}
}


}



/// <summary>
Expand All @@ -1491,6 +1431,9 @@ private void TaskStart_Click(object sender, RoutedEventArgs e)
/// <param name="e"></param>
private void TaskStop_Click(object sender, RoutedEventArgs e)
{
//改变任务列表状态
this.tasks_status = "stopped";

//遍历任务列表,查找当前任务
foreach (M3u8TaskItem item in this.m3u8_tasks)
{
Expand All @@ -1504,8 +1447,40 @@ private void TaskStop_Click(object sender, RoutedEventArgs e)

lbTaskList.Items.Refresh();

//改变任务列表状态
this.tasks_status = "stopped";
//终止logBlockReader写入
if (logBlockReader != null)
{
try
{
logBlockReader.Close();
logBlockReader = null;
}
catch (Exception ex)
{
MessageBox.Show($"中止下载Log读取器时出错:{ex.Message}");
}
}

//终止正在进行的下载进程
if (m3u8dlProcess != null)
{
try
{
m3u8dlProcess.Kill();
m3u8dlProcess.WaitForExit();
m3u8dlProcess.Close();
m3u8dlProcess = null;
}
catch (Exception ex)
{
MessageBox.Show($"中止下载进程出错:{ex.Message}");
}
}





}


Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@
添加够了之后,点击下载即可。

# 已知问题
## 停止并不会立刻停止
下载是调用 N_m3u8DL-CLI命令行工具 在另一个进程异步进行的。中途停止比较麻烦,并没有开发
## 停止的任务,不会再次开始
停止的任务,状态会被标记为"Stopped"。凡是状态不为空的任务,都会直接跳过。所以,再次下载前要重置状态

所以,简化之后,停止按钮的作用变成,完全当前这一个任务后停止,而不是立刻停止。
具体操作是:选择状态为Stopped的任务,点击按钮"重置"。

## 列表不能保存
m3u8地址经常一两个小时就会失效,所以就懒得做保存列表功能了。凑合吧。

## 特殊情况卡界面
下载时,程序会等待后台的N_m3u8DL-CLI命令行工具提供Log信息。如果 N_m3u8DL-CLI命令行工具 长时间不提供,本程序界面就会卡住。
Expand Down

0 comments on commit 3f147dc

Please sign in to comment.