Я работаю над программой, которая должна установить «n» множество SSH-соединений с удаленным сервером Linux и запускать команды времени для каждого соединения. «Операция, требующая много времени», в основном запускает скрипт, который настраивает Wireshark и слушает трафик.Остановка всех подключений SSH сразу
Для этого я использую библиотеку SharpSSH для C# и n много 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) подключается, подготавливает команды и запускает трудоемкую команду, после чего программа возвращается к пользовательскому интерфейсу, даже не запуская второе соединение. Это, очевидно, из-за цикла for, но я не мог понять, как это сделать.
Мне нужно, чтобы другой фоновый работник установил и запустил вторую команду со вторым сервером, так что, когда я нажимаю кнопку остановки в графическом интерфейсе, все соединения и потоки могут останавливаться вместе.
PS: Команды не останавливаются, если пользователь не нажимает кнопку остановки, которая посылает на сервер сигнал Ctrl-C.
Я относительно новичок во всех многопоточных и сетевых концепциях, поэтому, если есть какая-либо путаница или ошибка, сообщите мне.
Имейте славный день.
1) Предположим, вы, по крайней мере, сказали нам, что вызов «RunWorkerAsync» вызывается («bgw.IsBusy' является ложным) во втором раунде. –
2) Как вы инициализируете 'bwArray'? –
3) Вы обновили бы название вопроса, чтобы описать фактическую проблему (= вы не можете запустить несколько фоновых работников/соединений)? –