【发布时间】:2015-07-23 06:34:38
【问题描述】:
我正在开发一个程序,它应该与远程 Linux 服务器建立“n”个 SSH 连接,并在每个连接上运行耗时的命令。 “耗时操作”基本上是运行一个设置 Wireshark 并监听流量的脚本。
为此,我使用 C# 的 SharpSSH 库和许多 BackgroundWorkers 作为线程。同样为简单起见,下面的代码有 n=2 个 BGW 线程和 SSH 连接。
代码:
// runs when start is pressed
private void startButton_Click_1(object sender, EventArgs e)
{
sb = new StringBuilder();
DateTime timeNow = DateTime.Now;
clickTime = timeNow.ToString("yyyyMMddhhmmssfff"); // store the exact time of the click
bw = bwArray[0];
int index = 0; // ignore these 2 constants
foreach (BackgroundWorker bgw in bwArray)
{
if (bgw.IsBusy != true)
{
bgw.RunWorkerAsync();
// runWorkerAsync for every BackgroundWorker in the array
//index++;
}
}
}
// runWorkerAsync leads the BGWorker to this function
private void bw_doWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (worker.CancellationPending == true)
{
e.Cancel = true;
}
else
{
// let the UI know of button changes
int p = 0;
object param = "something"; // use this to pass any additional parameter back to the UI
worker.ReportProgress(p, param);
// UI notifying part ends here
// for the simplex case
if (numberOfConnections == 1)
startOperation();
// for the multiplex case
else if (numberOfConnections > 1)
{
//while (p < numberOfConnections)
//{
multiStartOperation();
// p++;
//}
}
Thread.Sleep(500);
}
}
// will be called for all ssh connections (in multiplex case)
private void multiStartOperation()
{
string[] command1Array = { "host2", "host2" };
string[] command2Array = { clickTime + "_h2", clickTime + "_h2" };
for (int index = 0; index < numberOfConnections; index++)
{
// shellArray is an array of SshExec objects
shellArray[index] = new SshExec(IPAddress, username, password);
try
{
shellArray[index].Connect();
}
catch (JSchException se)
{
Console.Write(se.StackTrace);
System.Windows.Forms.MessageBox.Show("Couldn't connect to the specified port.", "Connection Error!");
}
sb.Append(shellArray[index].RunCommand(command1Array[index]) + Environment.NewLine);
// first command is host3, or host4 etc.
// below is the time consuming command to run
string command = "./logcap.sh -c " + command2Array[index] + " -z";
// sb is a global stringBuilder object,
// to which the command output is appended
sb.Append(shellArray[index].RunCommand(command));
}
}
我的问题如下:
当我按下 GUI 上的开始按钮时,两个连接都应该启动并运行脚本。而在上面给出的代码中,shellArray 的第一个索引(由 SshExec 对象组成)被连接,准备命令并运行耗时的命令,此时程序返回 UI,甚至没有启动第二个连接。这显然是因为 for 循环,但我还不知道如何解决这个问题。
我需要让另一个后台工作程序与第二个服务器建立并运行第二个命令,这样当我按下 GUI 上的停止按钮时,所有连接和线程都可以一起停止。
PS:命令不会停止运行,除非用户单击停止,这会向服务器发送 Ctrl-C 信号。
我对所有多线程和网络概念都比较陌生,所以如果有任何混淆或错误,请告诉我。
祝你有美好的一天。
【问题讨论】:
-
1) 我想你至少告诉我们
RunWorkerAsync是否在第二轮被调用(bgw.IsBusy为假)。 -
2) 如何初始化
bwArray? -
3) 您是否会更新您的问题标题以描述实际问题(=您无法运行多个后台工作人员/连接)?
-
欢迎来到 Stack Overflow :)
标签: c# linux multithreading ssh backgroundworker