#c# #winforms #mvp
#c# #winforms #mvp
Вопрос:
я реализовал простой ProgressPresenter
public interface IProgressView
{
string Status { set; }
void SetProgress(int percentageDone);
void Display();
void Close();
event Action Closing;
}
class ProgressPresenter
{
private IProgressView m_view;
private ILongRunningTask m_task;
private bool m_completed;
public Progress(IProgressView view)
{
m_view = view;
}
public virtual void Display(ILongRunningTask task, string taskName)
{
m_task = task;
m_view.Status = taskName " is running";
m_view.Closing = OnClosing;
task.ProgressChanged = UpdateProgress;
task.Completed = Completed;
task.StartAsync();
m_view.Display();
m_view.Closing -= OnClosing;
task.ProgressChanged -= UpdateProgress;
task.Completed -= Completed;
}
protected virtual void UpdateProgress(object sender, ProgessEventArgs e)
{
m_view.SetProgress(e.AlreadyDone * 100 / e.Total);
}
protected virtual void Completed()
{
m_completed = true;
m_view.Status = "Completed";
m_view.Close();
}
private virtual void OnClosing()
{
if (!m_completed) m_downloader.Cancel();
}
}
Моя проблема в том, что задача выполняется в другом потоке, и каждый вызов представления (реализованный как Form
) выдает ошибку. Должен ли я обернуть каждый метод в форму, подобную
public string Status
{
set { Invoke(new Action(() => progressLabel.Text = value)); }
}
на всякий случай, если его можно вызвать из другого потока? или в Presenter есть недостатки?
Приветствуются любые советы
Ответ №1:
Да, вы должны это сделать. Я не знаю, какие другие библиотеки вы используете, но, вероятно, было бы неплохо добавить аспект ко всем вашим представлениям, чтобы сделать это за вас.
Также, возможно, стоило бы добавить пару удобных методов в базовом представлении; Например. У меня есть эти:
public void Invoke(Action action)
{
if (_control.InvokeRequired)
{
_control.Invoke(action);
return;
}
action();
}
public T Invoke<T>(Func<T> action)
{
if (_control.InvokeRequired)
return (T)_control.Invoke(action);
return action();
}
пример реализации aspect смотрите здесь
Комментарии:
1. спасибо за ответ. оба варианта довольно полезны. ATM Я не хочу зависимости от реального IOC, поэтому я создал свой собственный, очень простой, поэтому сейчас я выбираю второй вариант
2. Вы можете использовать Postsharp в качестве альтернативы аспектам, подобным прокси!