Шаг 247.
Язык программирования C#. Начала.
Многопоточное программирование. Использование потоков (окончание)

    На этом шаге мы рассмотрим еще один пример использования потоков.

    В следующем примере дочерний поток используется для вычисления суммы бесконечного ряда

("точное" значение этой бесконечной суммы равно 2е≈5,43656, где через е≈2,71828 обозначено основание натурального логарифма). Программа выполняет вычисления следующим образом. В главном методе объявляется double-переменная с начальным нулевым значением. Создается и запускается дочерний поток с бесконечным циклом. Там последовательно вычисляются слагаемые, и каждое вычисленное слагаемое прибавляется к текущему значению переменной, выделенной для запоминания значения суммы. При этом главный поток на время приостанавливает работу. После паузы из главного потока завершается выполнение дочернего потока, а вычисленное значение для суммы отображается в консольном окне. Программный код, в котором реализован описанный подход, представлен ниже.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;

namespace pr247_1
{
    class Program
    {
        // Главный метод: 
        static void Main()
        {
            // Переменная для записи значения суммы: 
            double s = 0;
            Console.WriteLine("Вычисление суммы");
            // Контрольное значение для суммы:
            Console.WriteLine("Koнтpoльнoe значение: {0}", 2 * Math.E);
            // Создание объекта потока:
            Thread calc = new Thread(()=>{
                // Индексная переменная: 
                int n = 1;
                // Добавка к сумме: 
                double q = 1;
                // Бесконечный цикл: 
                do {
                    // Прибавление слагаемого к сумме: 
                    s += q;
                    // Новое значение для индексной переменной: 
                    n++;
                    // Вычисление добавки к сумме 
                    // для следующего цикла: 
                    q = n * n;
                    for(int k = 1; k <= n; k++) { 
                        q /= k;
                    }
                    // Приостановка в выполнении потока: 
                    Thread.Sleep(100);
                } while (true);
            });
            // Запуск потока на выполнение: 
            calc.Start();
            // Приостановка выполнения главного потока: 
            Thread.Sleep(1000);
            // Завершение выполнения дочернего потока: 
            calc.Abort();
            // Отображение результата вычислений: 
            Console.WriteLine("Вычисленное значение: {0}", s);
        }
    }
}
Архив проекта можно взять здесь.

    Результат выполнения программы может быть таким, как показано ниже:


Рис.1. Результат работы приложения

    Думается, программный код особых комментариев не требует. Отметим лишь несколько обстоятельств. Во-первых, для сравнения приводится "точный" результат для суммы. Для этого мы использовали статическую константу E (основание натурального логарифма) из класса Math (пространство имен System). Во-вторых, слагаемые для суммы вычислялись "в лоб", без всяких упрощений и оптимизаций, строго в соответствии с формулой для слагаемого суммы. В-третьих, в дочернем потоке между прибавлением слагаемых к сумме выполнялась небольшая пауза. Делалось это с простой целью: чтобы дочерний поток не выполнялся слишком быстро и можно было проследить, как время вычисления суммы влияет на результат.

    На следующем шаге мы резюмируем все ранее сказанное по данной теме на предыдущих шагах.




Предыдущий шаг Содержание Следующий шаг