задача: есть множество операций типа переписывания файлов и всё такое, для
каждой операции известно сколько она всего занимает (например, байт), и
сколько уже сделано (например, переписано). нужно нарисовать несколько
прогресс-баров относительно некоторых множеств операций.
всё это осложняется тем, что порядок выполнения операций в некоторых случаях
может меняться, в некоторых не может, операции могут проваливаться и т.д.
ещё есть следующее осложнение -- мы можем планировать что операция займёт
некоторое кол-во единиц, но у функции которая занимается непосредственно
выполнением операции есть свои взгляды на это дело, это надо как-то
учитывать.э
вроде бы ничего страшного, но когда я попытался сделать это хоть как-то
более-менее цивилизованно.. в общем, в конец измученный, я просто завёл
переменные под каждое значение, влияющее на результат, потом написал
функцию, которая для каждого случая вычисляет прогресс, вроде-бы работает --
но, понятное дело, код жуток, много всякой дряни, сложно поддаётся изменению
и переиспользованию и т.д.
есть какие-нибудь идеи, как реализовать прогресс по-человечески?
With best regards, Alex Mizrahi.
AM> From: "Alex Mizrahi" <kill...@matfak.dongu.donetsk.ua>
AM> Hello, All!
AM> задача: есть множество операций типа переписывания файлов и всё такое,
AM> для каждой операции известно сколько она всего занимает (например, байт),
AM> и сколько уже сделано (например, переписано). нужно нарисовать несколько
AM> прогресс-баров относительно некоторых множеств операций.
AM> всё это осложняется тем, что порядок выполнения операций в некоторых
AM> случаях может меняться, в некоторых не может, операции могут
AM> проваливаться и т.д.
AM> ещё есть следующее осложнение -- мы можем планировать что операция займёт
AM> некоторое кол-во единиц, но у функции которая занимается непосредственно
AM> выполнением операции есть свои взгляды на это дело, это надо как-то
AM> учитывать.э
AM> вроде бы ничего страшного, но когда я попытался сделать это хоть как-то
AM> более-менее цивилизованно.. в общем, в конец измученный, я просто завёл
AM> переменные под каждое значение, влияющее на результат, потом написал
AM> функцию, которая для каждого случая вычисляет прогресс, вроде-бы работает
AM> -- но, понятное дело, код жуток, много всякой дряни, сложно поддаётся
AM> изменению
AM> и переиспользованию и т.д.
AM> есть какие-нибудь идеи, как реализовать прогресс по-человечески?
Когда я решал ту же задачу, все операции писались для двух режимов - посчитать
сколько нужно тиков прогресс-бара и непосредственно выполнить действие.
Прогресс-баром управляет сама операция естественно, чтобы в случае ее
изменения не надо было лезть в другие места...
Но в целом насколько я понимаю сделать, чтобы прогрессбар шел ровно, несмотря
на то что внутри совершенно разные операции (например, запись в бд и
копирование файлов), практически нельзя.
WBR, Lazarev Dmitri.
Alex Mizrahi wrote to All:
AM> задача: есть множество операций типа переписывания файлов и всё такое, для
AM> каждой операции известно сколько она всего занимает (например, байт), и
AM> сколько уже сделано (например, переписано). нужно нарисовать несколько
AM> прогресс-баров относительно некоторых множеств операций.
AM> есть какие-нибудь идеи, как реализовать прогресс по-человечески?
Очень просто. Следующий BL объект:
class OperationInfo
{
//Singleton
public static OperationInfo Default {get; set;}
//Registering functions (for BL code implementing operations)
public void Start(string operation, int totalSteps);
public void Step(string operation, optional int steps = 1);
public void Stop(string operation);
//Type declarations for GUI
public event StartEventHandler(int totalSteps);
public event StepEventHandler(int currentProgress);
public event StopEventHandler();
//Reporting functions (for GUI)
public void RegisterForOperation(
string operation,
StartEventHandler onStart,
StepEventHandler onStep,
StopEventHandler onStop);
public int GetTotalSteps(string operation);
public int GetCurrentProgress(string operation);
}
пример BL кода:
ArrayList files = GetFilesToCopy();
OperationInfo.Default.Start("fileCopy", files.Count);
try
{
foreach(string filename in files)
{
File.Copy(filename, filename + "blabla");
OperationInfo.Default.Step("fileCopy", 1);
}
}
finally
{
OperationInfo.Default.Stop("fileCopy");
}
примечание - при необходимости можно добавить еще один параметр в Step - string
message.
Пример GUI кода, работающего на events:
в Init():
OperationInfo.Default.RegisterForOperation("fileCopy", OnStart, OnStep,
OnStop);
public void OnStart(int total)
{
_progressBar.Visible = true;
_progressBar.Max = total;
}
public void OnStep(int currentStep)
{
_progressBar.Val = currentStep;
}
public void OnStop()
{
_progressBar.Visible = false;
}
пример GUI без использования events - вызывать следующий метод три раза в
секунду:
public void UpdateProgress()
{
if(_progressBar.Visible)
{
_progressBar.Val =
OperationInfo.Default.GetCurrentProgress("fileCopy");
}
else
{
if(OperationInfo.Default.GetTotalSteps("fileCopy") > 0)
{
_progressBar.Visible = true;
_progressBar.Max = OperationInfo.Default.GetTotalSteps("fileCopy");
}
}
}
В зависимости от имплементации OperationInfo его можно еще и использовать для
logging.
See you.