Есть у нас числовые вычисления (голый 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));
}
}
Здравствуйте, Kore Sar, Вы писали:
KS>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты.
Отменить в смысле прервать вычисления или в смысле вернуть состояние подсчётов к тому, что было до их начала?
Если прервать, то прерывать можно с сохранением достигнутых результатов и корректного состояния расчётов, и без сохранения. Первое подразумевает разбиение расчётов на этапы, между которыми можно их прекратить и, возможно, сохранить состояние вычислений. Код, ведущий расчёты, пишется с учётом наличия некоего флага, по взведению которого надо не приступать к очередной порции расчётов, а прерваться. Если нужно просто остановить вычисления, то также можно проверять флаг, но при этом нас не заботит, в каком состоянии будет то, что мы вычисляли.
Чем выше частота проверок и больше количество этапов, тем выше скорость реакции системы на управляющее воздействие, но тем больше холостых действий. Компромисс подбирается экспериментально, исходя из ТЗ.
Если же надо откатить расчёты, то тут либо надо запоминать где-то состояние расчётов до их начала, и в случае прерывания просто их восстанавливать, либо проводить расчёты так, чтобы их можно было обратить.
Здравствуйте, Kore Sar, Вы писали:
KS>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке. KS>Я рассматривал варианты: KS>1) Иметь bool cancelled переменную (ГДЕ?),
В некоем контексте, который протягивать как параметр вычислений. Или можно немного отвязаться через TLS [ThreadAttribute]. Только грузи ссылку на контекст на стек в начале ф-ии, если в ее теле будешь в цикле проверять, вроде быстрее работает, чем дергать TLS каждый раз.
KS>проверять на очередной итерации и, если что, делать return null (или кидать exception).
Лучше второе, сэкономишь многие if/return на сильновложенных/разветвленных вычислениях и вообще кошернее.
KS>2) Обрывать поток нафиг.
Для дотнета и это потянет, можно существенно сэкономить на лишних проверках volatile-переменной и дерганье TLS. Единственно что, перед обрыванием используй тот же мьютекс для синхронизации, которым защищается результат.
Здравствуйте, LeonidV, Вы писали:
LV>Здравствуйте, Aviator, Вы писали:
A>>Т.е. вместо того, что бы аккуратно написать алгоритм расчёта предлагаем написать коекак и на всякий случай запузырить в отдельный процесс, что бы нестабильный алгоритм не грохал вместе с собой всё приложение ? Такой подход очень распостранён во многих НИИ где по году — два работают студенты и особо героическая личность пытается воспользоваться результатом их усердного труда, ибо по другому никак.
LV>Может там есть какая особенность задачи, которую я не уловил, но мне вариант "запустить в отдельном потоке и прибить при необходимости" кажется вполне адекватным в том случае, если такое резкое прирывание ничего не сломает. Как сам алгоритм связан с его запуском мне до конца не понятно. Более того, иногда нужно делать прерываемые задачи, которые включают в себя сторонний код, добавление в которого переменной mustBreak ну никак не возможно.
Автор привёл достаточно конкретную задачу, а не абстрактное выполнение чего либо асинхронно, хотя он не привёл примера распаралеливания. По описанию автора это сугубо алгоритмическя задача обхода дерева в памяти, стандартное решение использовать для этого потоки, а не процессы, сервера, кластеры. Тут кстати писалось про TLS — не забываем что потом может быть не один.
A>>ЗЫ А "чисто потоку" что данные не нужны или вы будете героически маршалить дерево объектов в другой процесс и потом из него получать дерево представляющее результат операции?. LV>Если само дерево не меняется, или под каждое вычисление заводится свое дерево, то ничего страшного не будет. Не знаю как в .NET, в Java проблемы ожидания асинхронного выполнения процесса решены в версии 1.5, кажется.
Я рад за Java, только причём тут проблемы асинхронного ожидания завершения потока?
Здравствуйте, Kore Sar, Вы писали:
KS>Здрасьте.
KS>Есть у нас числовые вычисления (голый C#). Дерево объектов проходится вдоль и поперёк, и для каждого листка считаются значения. Выглядит примерно так: KS>
KS>Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты. Приложение многопоточное. Клик пользователя происходит в другом потоке. KS>Я рассматривал варианты: KS>1) Иметь bool cancelled переменную (ГДЕ?), проверять на очередной итерации и, если что, делать return null (или кидать exception). KS>2) Обрывать поток нафиг. KS>3) Ваш вариант...
KS>Кто делал подобное, подскажите правильный путь. Спасибо.
Вот как это делается в WPF с помощью BackgroundWorker:
Смотрите метод CancelAsync и cвойство CancellationPending.
В любом случае надо будет вводить в ваш код специальную переменную.
Трудно быть богом(с) A.C. и Б.С.
Re[7]: Cancellable calculations. Научите.
От:
Аноним
Дата:
21.08.10 05:15
Оценка:
Здравствуйте, Aviator, Вы писали:
A>Т.е. вместо того, что бы аккуратно написать алгоритм расчёта предлагаем написать коекак и на всякий случай запузырить в отдельный процесс, что бы нестабильный алгоритм не грохал вместе с собой всё приложение ? Такой подход очень распостранён во многих НИИ где по году — два работают студенты и особо героическая личность пытается воспользоваться результатом их усердного труда, ибо по другому никак.
Такой подход распространен везде, где требуется хоть какая-то надежность. Потому что в противном случае придется формально доказывать корректность расчетного алгоритма, а потом еще и корректность имплементации. То, что такими вещами занимаются в НИИ, а не в бизнесе, -- ну так повелось.
Более того, на уровне железа это вообще одна из общеупотребительных практик: если основному процессору нравится поведение переферийного устройства, он на пытается разобраться, что произошло, а сразу посылает устройству reset и продолжает работу из гарантированно корректного состояния. Потому что некорректное состояние может быть вызвано некстати подвернувшейся заряженной частицей.
A>Т.е. вместо того, что бы аккуратно написать алгоритм расчёта предлагаем написать коекак и на всякий случай запузырить в отдельный процесс, что бы нестабильный алгоритм не грохал вместе с собой всё приложение ?
Это тут при чём?
Кто говорил про нестабильный алгоритм?
Нужно сделать так, чтобы по "знаку свыше" (клику пользователя) можно было отменить все эти подсчеты.
Как из этой фразы можно было развить мысль про НИИ и студентов, пишущих алгоритмы, которые постоянно вываливаются — мне неведомо