Есть у нас числовые вычисления (голый C#). Дерево объектов проходится вдоль и поперёк, и для каждого листка считаются значения. Выглядит примерно так:
public Result Calculate(Parameters parameters)
{
if (this.IsLeaf)
{
return this.GetCalculationFormulaStrategy(parameters).Calculate();
}
else
{
return this.ListAllChilds().Aggregate(child => child.Calculate(parameters));
}
}
Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке.
Я рассматривал варианты:
1) Иметь bool cancelled переменную (ГДЕ?), проверять на очередной итерации и, если что, делать return null (или кидать exception).
2) Обрывать поток нафиг.
3) Ваш вариант...
Кто делал подобное, подскажите правильный путь. Спасибо.
Здравствуйте, Kore Sar, Вы писали:
KS>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке.
Здравствуйте, Kore Sar, Вы писали:
KS>Здрасьте.
KS>Есть у нас числовые вычисления (голый C#). Дерево объектов проходится вдоль и поперёк, и для каждого листка считаются значения. Выглядит примерно так: KS>
KS>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке. KS>Я рассматривал варианты: KS>1) Иметь bool cancelled переменную (ГДЕ?), проверять на очередной итерации и, если что, делать return null (или кидать exception). KS>2) Обрывать поток нафиг. KS>3) Ваш вариант...
Вводить переменную CancelRequested и везде её проверять. Приложение многопоточным само по себе не станет, как вы используете многопоточность? От этого зависит ответ на вопрос ГДЕ.
Здравствуйте, MozgC, Вы писали:
MC>Здравствуйте, ___Avatar___, Вы писали:
___>>сделать все в отдельном процессе и убивать процесс со стороны без лишних вопросов
MC>Ага, можно еще запускать на специальным выделенном сервере и отключать ему электричество.
Не смешно.
Человек либо попутал слова "процесс" и "поток", либо сильно ошибся.
Здравствуйте, MozgC, Вы писали:
MC>Здравствуйте, ___Avatar___, Вы писали:
___>>сделать все в отдельном процессе и убивать процесс со стороны без лишних вопросов
MC>Ага, можно еще запускать на специальным выделенном сервере и отключать ему электричество.
но это же чисто математический поток, не использующий внешние ресурсы в виде сокетов, файлов и БД
поэтому наверное лучше выделить в процесс и убить
Здравствуйте, Kore Sar, Вы писали:
KS>Здравствуйте, MozgC, Вы писали:
MC>>Здравствуйте, ___Avatar___, Вы писали:
___>>>сделать все в отдельном процессе и убивать процесс со стороны без лишних вопросов
MC>>Ага, можно еще запускать на специальным выделенном сервере и отключать ему электричество.
KS>Не смешно. KS>Человек либо попутал слова "процесс" и "поток", либо сильно ошибся.
сильно ошибся
я давнопод виндой программировал
под дот нет вообще почти не работал
поэтому ответил с точки зрения того, как бы я это сделал на vc++ и дельфях
Здравствуйте, ___Avatar___, Вы писали:
___>Здравствуйте, MozgC, Вы писали:
MC>>Здравствуйте, ___Avatar___, Вы писали:
___>>>сделать все в отдельном процессе и убивать процесс со стороны без лишних вопросов
MC>>Ага, можно еще запускать на специальным выделенном сервере и отключать ему электричество.
___>но это же чисто математический поток, не использующий внешние ресурсы в виде сокетов, файлов и БД ___>поэтому наверное лучше выделить в процесс и убить
___>почему этоплохо?
А почему плохо на отдельном сервере?
Здравствуйте, Aviator, Вы писали:
A>Здравствуйте, ___Avatar___, Вы писали:
___>>Здравствуйте, MozgC, Вы писали:
MC>>>Здравствуйте, ___Avatar___, Вы писали:
___>>>>сделать все в отдельном процессе и убивать процесс со стороны без лишних вопросов
MC>>>Ага, можно еще запускать на специальным выделенном сервере и отключать ему электричество.
___>>но это же чисто математический поток, не использующий внешние ресурсы в виде сокетов, файлов и БД ___>>поэтому наверное лучше выделить в процесс и убить
___>>почему этоплохо? A>А почему плохо на отдельном сервере?
я понимаю, что вообще с точки зрения "чистого программирования" — это плохо
но с точки зрения здравого смысла нормально
(я про убийство процесса, а не сервера)
при убийстве математического процесса все ресурсы вроде бы быстро освобождаются
а если есть какие-то заморрочки с автоматическим освобождением этих ресурсов под дот нетом, то наверняка их можно освободить искусственно
Здравствуйте, Aviator, Вы писали:
A>Вводить переменную CancelRequested и везде её проверять. Приложение многопоточным само по себе не станет, как вы используете многопоточность? От этого зависит ответ на вопрос ГДЕ.
Сейчас используем System.Threading.Timer вроде как.
Но подключена PFX. Так что можем и через System.Threading.Task если чо.
Как лучше, так и сделаем.
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, Kore Sar, Вы писали:
KS>>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке.
N>В .NET 4.0 для этого есть целая инфраструктура.
Здравствуйте, ___Avatar___, Вы писали:
___>Здравствуйте, Aviator, Вы писали:
A>>Здравствуйте, ___Avatar___, Вы писали:
___>>>Здравствуйте, MozgC, Вы писали:
MC>>>>Здравствуйте, ___Avatar___, Вы писали:
___>>>>>сделать все в отдельном процессе и убивать процесс со стороны без лишних вопросов
MC>>>>Ага, можно еще запускать на специальным выделенном сервере и отключать ему электричество.
___>>>но это же чисто математический поток, не использующий внешние ресурсы в виде сокетов, файлов и БД ___>>>поэтому наверное лучше выделить в процесс и убить
___>>>почему этоплохо? A>>А почему плохо на отдельном сервере?
___>я понимаю, что вообще с точки зрения "чистого программирования" — это плохо ___>но с точки зрения здравого смысла нормально ___>(я про убийство процесса, а не сервера) ___>при убийстве математического процесса все ресурсы вроде бы быстро освобождаются ___>а если есть какие-то заморрочки с автоматическим освобождением этих ресурсов под дот нетом, то наверняка их можно освободить искусственно
Т.е. вместо того, что бы аккуратно написать алгоритм расчёта предлагаем написать коекак и на всякий случай запузырить в отдельный процесс, что бы нестабильный алгоритм не грохал вместе с собой всё приложение ? Такой подход очень распостранён во многих НИИ где по году — два работают студенты и особо героическая личность пытается воспользоваться результатом их усердного труда, ибо по другому никак.
ЗЫ А "чисто потоку" что данные не нужны или вы будете героически маршалить дерево объектов в другой процесс и потом из него получать дерево представляющее результат операции?.
Здравствуйте, ___Avatar___, Вы писали:
___>почему этоплохо?
Потому что это стандартная задача которая имеет стандартные решения (см. ответы nikov и Aviator). В данной ситуации создавать для этого отдельный процесс — это решение задачи через "одно место", к тому же придется осуществлять межпроцессорное взаимодействие, т.е. чтобы процесс-калькулятор передавал результаты родительскому процессу.
A>Т.е. вместо того, что бы аккуратно написать алгоритм расчёта предлагаем написать коекак и на всякий случай запузырить в отдельный процесс, что бы нестабильный алгоритм не грохал вместе с собой всё приложение ? Такой подход очень распостранён во многих НИИ где по году — два работают студенты и особо героическая личность пытается воспользоваться результатом их усердного труда, ибо по другому никак.
A>ЗЫ А "чисто потоку" что данные не нужны или вы будете героически маршалить дерево объектов в другой процесс и потом из него получать дерево представляющее результат операции?.
в принципе оба подхода хороши в зависимости от ситуации
даже подход с сервером и обрубанием у него питания тоже нормальный
надо знать все детали ситуации, чтобы ответить правильно
я понимаю, что с точки зрения "чистого программирования" мое предложение абсолютно некорректно
Здравствуйте, Kore Sar, Вы писали:
KS>Здравствуйте, Aviator, Вы писали:
A>>Вводить переменную CancelRequested и везде её проверять. Приложение многопоточным само по себе не станет, как вы используете многопоточность? От этого зависит ответ на вопрос ГДЕ.
KS>Сейчас используем System.Threading.Timer вроде как. KS>Но подключена PFX. Так что можем и через System.Threading.Task если чо. KS>Как лучше, так и сделаем.
Я вообще имел в виду структуру кода, ну да ладно. В любом случае у вас будет объект, моделирующий задачу на выполнение (не поток а задачу). В этом или каком-либо вспомогательном объекте будет потокобезопасный метод Cancel() который собственно и осуществит завершение операции. В вашем случае это будет вероятно установка флага запроса остановки. ДляЗадача должна быть разбита на недлительные подзадачи, точнее на этапы выполнения, и при переходе от этапа к этапу осуществляется проверка флага. Флаг можно поместить как поле задачи или передавать в задачу специальный объект c полем типа CancelRequested.
A>>Т.е. вместо того, что бы аккуратно написать алгоритм расчёта предлагаем написать коекак и на всякий случай запузырить в отдельный процесс, что бы нестабильный алгоритм не грохал вместе с собой всё приложение ? Такой подход очень распостранён во многих НИИ где по году — два работают студенты и особо героическая личность пытается воспользоваться результатом их усердного труда, ибо по другому никак.
A>>ЗЫ А "чисто потоку" что данные не нужны или вы будете героически маршалить дерево объектов в другой процесс и потом из него получать дерево представляющее результат операции?.
___>в принципе оба подхода хороши в зависимости от ситуации ___>даже подход с сервером и обрубанием у него питания тоже нормальный ___>надо знать все детали ситуации, чтобы ответить правильно
___>я понимаю, что с точки зрения "чистого программирования" мое предложение абсолютно некорректно
С точки зрения практического программирования передать контекст данных в другой процесс может представлять отдельную задачу с конвертацией дерева объектов доменной модели в набор дто и построением новой модели в серверном процессе.
Здравствуйте, nikov, Вы писали:
KS>>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке.
N>В .NET 4.0 для этого есть целая инфраструктура.
Так это ж без самих тасков вроде бы никуда не прикрутишь?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Aviator, Вы писали:
A>Т.е. вместо того, что бы аккуратно написать алгоритм расчёта предлагаем написать коекак и на всякий случай запузырить в отдельный процесс, что бы нестабильный алгоритм не грохал вместе с собой всё приложение ? Такой подход очень распостранён во многих НИИ где по году — два работают студенты и особо героическая личность пытается воспользоваться результатом их усердного труда, ибо по другому никак.
Может там есть какая особенность задачи, которую я не уловил, но мне вариант "запустить в отдельном потоке и прибить при необходимости" кажется вполне адекватным в том случае, если такое резкое прирывание ничего не сломает. Как сам алгоритм связан с его запуском мне до конца не понятно. Более того, иногда нужно делать прерываемые задачи, которые включают в себя сторонний код, добавление в которого переменной mustBreak ну никак не возможно.
A>ЗЫ А "чисто потоку" что данные не нужны или вы будете героически маршалить дерево объектов в другой процесс и потом из него получать дерево представляющее результат операции?.
Если само дерево не меняется, или под каждое вычисление заводится свое дерево, то ничего страшного не будет. Не знаю как в .NET, в Java проблемы ожидания асинхронного выполнения процесса решены в версии 1.5, кажется.
Здравствуйте, Kore Sar, Вы писали:
KS>Здрасьте.
KS>Есть у нас числовые вычисления (голый C#). Дерево объектов проходится вдоль и поперёк, и для каждого листка считаются значения. Выглядит примерно так: KS>
KS>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке. KS>Я рассматривал варианты: KS>1) Иметь bool cancelled переменную (ГДЕ?), проверять на очередной итерации и, если что, делать return null (или кидать exception). KS>2) Обрывать поток нафиг. KS>3) Ваш вариант...
KS>Кто делал подобное, подскажите правильный путь. Спасибо.
В эклипсе повсеместно используется такой подход (псевдокод):
public Result Calculate(Parameters parameters, IProgressMonitor monitor)
{
if(monitor.isCanceled()) return null;
if (this.IsLeaf)
{
return this.GetCalculationFormulaStrategy(parameters).Calculate(); //or Calculate(monitor) if necessary
}
else
{
return this.ListAllChilds().Aggregate(child => child.Calculate(parameters, monitor));
}
}