private void buttonParallelSearch_Click(object sender, EventArgs e) { //Слово для поиска string word = this.textBoxFind.Text.Trim(); //Если слово для поиска не пусто if (!string.IsNullOrWhiteSpace(word) && list.Count > 0) { //максимальное расстояние int maxDist; if (!int.TryParse(this.textBoxMaxDist.Text.Trim(), out maxDist)) { MessageBox.Show("Необходимо указать максимальное расстояние"); return; } if (maxDist < 1 || maxDist > 5) { MessageBox.Show("Максимальное расстояние должно быть в диапазоне от 1 до 5"); return; } //количество потоков int ThreadCount; if (!int.TryParse(this.textBoxThreadCount.Text.Trim(), out ThreadCount)) { MessageBox.Show("Необходимо указать количество потоков"); return; } //время поиска Stopwatch timer = new Stopwatch(); timer.Start(); //------------------------------------------------- // Начало параллельного поиска //------------------------------------------------- //Результирующий список //List<ParallelSearchResult> Result = new List<ParallelSearchResult>(); //Деление списка на фрагменты для параллельного запуска в потоках List<MinMax> arrayDivList = SubArrays.DivideSubArrays(0, list.Count, ThreadCount); int count = arrayDivList.Count; //Количество потоков соответствует количеству фрагментов массива //Task<List<ParallelSearchResult>>[] tasks = new Task<List<ParallelSearchResult>>[count]; //Запуск потоков for (int i = 0; i < count; i++) { //Создание временного списка, чтобы потоки не работали параллельно с одной коллекцией List<string> tempTaskList = list.GetRange(arrayDivList[i].Min, arrayDivList[i].Max - arrayDivList[i].Min); //tasks[i] = new Task<List<ParallelSearchResult>>( //Метод, который будет выполняться в потоке // ArrayThreadTask, //Параметры потока //new ParallelSearchThreadParam() //{ // tempList = tempTaskList, // maxDist = maxDist, // ThreadNum = i, // wordPattern = word //}); //Запуск потока //tasks[i].Start(); // } //Task.WaitAll(tasks); //timer.Stop(); ////Объединение результатов //for (int i = 0; i < count; i++) //{ // Result.AddRange(tasks[i].Result); //} //------------------------------------------------- // Завершение параллельного поиска //------------------------------------------------- timer.Stop(); //Вывод результатов //Время поиска // this.textBoxApproxTime.Text = timer.Elapsed.ToString(); //Вычисленное количество потоков this.textBoxThreadCountAll.Text = count.ToString(); //Начало обновления списка результатов this.listBoxParallelResult.BeginUpdate(); //Очистка списка this.listBoxParallelResult.Items.Clear(); //Вывод результатов поиска foreach (var x in Result) { string temp = x.word + "(расстояние=" + x.dist.ToString() + " поток=" + x.ThreadNum.ToString() + ")"; this.listBoxParallelResult.Items.Add(temp); } //Окончание обновления списка результатов this.listBoxParallelResult.EndUpdate(); } else { MessageBox.Show("Необходимо выбрать файл и ввести слово для поиска"); } }
//Многопоточный поиск в массиве public static void ArrayThreadExample(int ArrayLength, int ThreadCount, int Divider) { //Результирующий список чисел List <int> Result = new List <int>(); //Создание и заполнение временного списка данных List <int> tempList = new List <int>(); for (int i = 0; i < ArrayLength; i++) { tempList.Add(i + 1); } //Деление списка на фрагменты //для параллельного запуска в потоках List <MinMax> arrayDivList = SubArrays.DivideSubArrays(0, ArrayLength, ThreadCount); int count = arrayDivList.Count; //Вывод диапазонов деления исходного массива for (int i = 0; i < count; i++) { //Вывод результатов, найденных в каждом потоке Console.WriteLine("Диапазон " + i.ToString() + ": " + arrayDivList[i].Min + " - " + arrayDivList[i].Max); } Console.WriteLine(); //Создание таймера Stopwatch timer = new Stopwatch(); //Запуск таймера timer.Start(); //Количество потоков соответствует количеству фрагментов массива Task <List <int> >[] tasks = new Task <List <int> > [count]; //Запуск потоков for (int i = 0; i < count; i++) { //Создание временного списка, чтобы потоки //не работали параллельно с одной коллекцией List <int> tempTaskList = tempList.GetRange(arrayDivList[i].Min, arrayDivList[i].Max - arrayDivList[i].Min); tasks[i] = new Task <List <int> >( //Метод, который будет выполняться в потоке ArrayThreadTask1, //Параметры потока передаются в виде кортежа, чтобы не создавать временный класс new Tuple <List <int>, int>(tempTaskList, Divider)); //Запуск потока tasks[i].Start(); } //Ожидание завершения всех потоков Task.WaitAll(tasks); //Остановка таймера timer.Stop(); //Объединение результатов полученных из разных потоков for (int i = 0; i < count; i++) { //Вывод результатов, найденных в каждом потоке Console.Write("Поток " + i.ToString() + ": "); foreach (var x in tasks[i].Result) { Console.Write(x.ToString() + " "); } Console.WriteLine(); //Добавление результатов конкретного потока //в общий массив результатов Result.AddRange(tasks[i].Result); } //Вывод общего массива результатов Console.WriteLine("\nМассив из {0} элементов обработан {1} потоками за { 2}. Найдено: { 3} ", ArrayLength, count, timer.Elapsed, Result.Count); foreach (int i in Result) { Console.Write(i.ToString().PadRight(5)); } Console.WriteLine(); }