Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Мелкие непонятки с потоками и (?) делегатами


Автор: Urvin 27.6.2010, 12:35
Я в сишарпе только начинаю, хотя с другими языками прекрасно имел дело.
Столкнулся с необходимостью использования потока в одном из моих модулей. Здесь поток является неким дополнительным объектом, в отличие от прочих ЯП, где для действий в отдельном потоке используется наследование. 
Видимо, этот стереотип и не дает мне никак разобраться.

Задача такова: есть  класс примерно такого содержания:
Код

public class MyClass
{
    private int a;
    private int b;

    public MyClass()
    {
        a = 0;
        b = 0;
    }

    //--------------------------------------------------------//

    protected void doCalculateA()
    {
        while (a < 1000)
            a++;
    }

    protected void doCalculateB
    {
        while (b < 10000)
            b++;
    }

    //--------------------------------------------------------//

    protected void doCalculateAandB()
    {
        doCalculateA();
        // Тут вызвать событие, что А подготовлено

        doCalculateB();
        // Тут вызвать событие, что В подготовлено
    }

    //--------------------------------------------------------//

    public void Calculate()
    {
        Thread lThread = new Thread(doCalculateAandB);
        lThread.Start();

        lThread.Join();
        // Вызвать событие об окончании работы потока
    }
}


lThread.Join() лишний, но пока не понимаю как избавиться от него.

Извне я могу вызвать только MyClass.Calculate(), от которой мне хотелось бы выполнения в отдельном потоке,  а также высылку событий об окончании расчета переменной А, переменной Б и завершении потока.
 Т.е. форма вызова должна быть примерно такой:

Код

private void OnACalculated(int aErrorCode)
{
    // прием события о расчете А
}

private void OnВCalculated(int aErrorCode)
{
    // прием события о расчете А
}

private void OnThreadFinished()
{
    // прием события об окончании работы треда
}

...

MyClass lCalculator = new MyClass;
lCalculator.OnACalculated = OnACalculated;
lCalculator.OnBCalculated = OnBCalculated;
lCalculator.OnThreadFinished = OnThreadFinished;
lCalculator.Calculate();


Подскажите, пожалуйста, как мне правильно запустить вычисления в отдельном потоке и правильно описать событийную модель?

Автор: Partizan 28.6.2010, 13:57
Urvin, я думаю стоит посмотреть BackgroundWorker.

Автор: MrDale 29.6.2010, 12:59
Можно так:
Код

        public Action<Exception> OnCalculatedA;
        public Action<Exception> OnCalculatedB;
        public Action OnThreadFinished;

        protected void doCalculateAandB()
        {
            Exception error = null;
            try
            {
                doCalculateA();
            }
            catch (Exception ex)
            {
                error = ex;
            }
            if (OnCalculatedA != null)
                OnCalculatedA(error);

            error = null;
            try
            {
                doCalculateB();
            }
            catch (Exception ex)
            {
                error = ex;
            }
            if (OnCalculatedB != null)
                OnCalculatedB(error);

            if (OnThreadFinished != null)
                OnThreadFinished();
        }


Только учтите что OnXXX будут вызвать в том-же дополнительном потоке.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)