• Бесплатный ВЕБИНАР по OSINT с Екатериной Тьюринг: ➡️9 февраля в 19:00 (мск) пройдет урок

    Как безопасно искать информацию в открытых источниках

    🔥 Записаться 🔥

Многопоточность, Progressbar!

  • Автор темы Автор темы KIA1990
  • Дата начала Дата начала
K

KIA1990

Доброго времени суток!
Проблема такая:
У меня есть класс(dll), работает очень очень долго
и есть форма на которой желательно бы отследить работу класса(метода).
Не могу понять как это сделать!

В отдельный поток нужно передавать void методы без параметров??
Или как то можно с параметрами, просто необходимо передать методу FileStram.


Вот. :huh:
 
Наиболее простой вариант отслеживания: сделать в твоем классе событие, аргумент которого содержал бы текущий прогресс. Далее, по мере выполнения "долгоиграющего" метода время от времени дергать это событие. Обработчик события будет обновлять прогресс бар.
Класс будет выглядеть примерно так:
Код:
public class ProgressChangedEventArgs : EventArgs
{
public int CurrentProgress { get; set; }
}

public delegate void ProgressChangedHandler(object sender, ProgressChangedEventArgs e);

public class WorkingClass
{
public event ProgressChangedHandler ProgressChanged;

private void OnProgressChanged(int progress)
{
ProgressChangedHandler handler = this.ProgressChanged;
if (handler != null)
handler(this, new ProgressChangedEventArgs { CurrentProgress = progress });
}

private void DoLotsOfWork(object data)
{
// Достаем FileStream
FileStream stream = data as FileStream;
if (stream == null)
throw ArgumentException("Надо было все-таки передать нормальный FileStream", "data");

OnProgressChanged(0);

// Делаем один кусок работы, скажем, четверть, после чего сообщаем об этом "наверх"
...
OnProgressChanged(25);

// Делаем еще один кусок, скажем, уже 2/3 работы сделано
...
OnProgressChanged(66);

//Ну и вроде как все доделали
...
OnProgressChanged(100);
}

public Thread DoLotsOfWorkAsync(FileStream stream)
{
Thread thread = new Thread(new ParameterizedThreadStart(this.DoLotsOfWork));
thread.Start(stream);

return thread;
}
}
Соответственно, использоваться это добро будет примерно так:
Код:
WorkingClass wc = new WorkingClass();
wc.ProgressChanged += delegate (object sender, ProgressChangedEventArgs e)
{
if (progressBar.InvokeRequired)
progressBar.Invoke(delegate (int progress) { progressBar.Value = progress; },
new Object[] { e.CurrentProgress });
else
progressBar.Value = e.CurrentProgress;
};

FileStream stream = ...;
ws.DoLotsOfWorkAsync(stream);
 
Наиболее простой вариант отслеживания: сделать в твоем классе событие, аргумент которого содержал бы текущий прогресс. Далее, по мере выполнения "долгоиграющего" метода время от времени дергать это событие. Обработчик события будет обновлять прогресс бар.
Класс будет выглядеть примерно так:
Код:
public class ProgressChangedEventArgs : EventArgs
{
public int CurrentProgress { get; set; }
}

public delegate void ProgressChangedHandler(object sender, ProgressChangedEventArgs e);

public class WorkingClass
{
public event ProgressChangedHandler ProgressChanged;

private void OnProgressChanged(int progress)
{
ProgressChangedHandler handler = this.ProgressChanged;
if (handler != null)
handler(this, new ProgressChangedEventArgs { CurrentProgress = progress });
}

private void DoLotsOfWork(object data)
{
// Достаем FileStream
FileStream stream = data as FileStream;
if (stream == null)
throw ArgumentException("Надо было все-таки передать нормальный FileStream", "data");

OnProgressChanged(0);

// Делаем один кусок работы, скажем, четверть, после чего сообщаем об этом "наверх"
...
OnProgressChanged(25);

// Делаем еще один кусок, скажем, уже 2/3 работы сделано
...
OnProgressChanged(66);

//Ну и вроде как все доделали
...
OnProgressChanged(100);
}

public Thread DoLotsOfWorkAsync(FileStream stream)
{
Thread thread = new Thread(new ParameterizedThreadStart(this.DoLotsOfWork));
thread.Start(stream);

return thread;
}
}
Соответственно, использоваться это добро будет примерно так:
Код:
WorkingClass wc = new WorkingClass();
wc.ProgressChanged += delegate (object sender, ProgressChangedEventArgs e)
{
if (progressBar.InvokeRequired)
progressBar.Invoke(delegate (int progress) { progressBar.Value = progress; },
new Object[] { e.CurrentProgress });
else
progressBar.Value = e.CurrentProgress;
};

FileStream stream = ...;
ws.DoLotsOfWorkAsync(stream);

Спасибо!
Дело то все в том, что работа зависит от размера файла, то есть я не могу точно указать на каком участке метода сделано определенное количество работы,
так как файл разбивается на части, методы работают по несколько раз
 
Дело то все в том, что работа зависит от размера файла, то есть я не могу точно указать на каком участке метода сделано определенное количество работы,
так как файл разбивается на части, методы работают по несколько раз
Если файл разбивается на части, то события изменения прогресса можно пулять после обработки очередной части, если количество частей заранее известно. Если файл обрабатывается построчно/побайтно, то можно получить его размер перед началом обработки и сообщать о прогрессе по мере считывания очередного фрагмента.
Вероятно, в конечном итоге не получится абсолютно точное отображение прогресса, но это, как правило, и не нужно: главное, что пользователь уже видит, что программа что-то делает и примерно может оценить, сколько времени это займет.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!