mvp асинхронный прогресс winforms - PullRequest
1 голос
/ 11 ноября 2011

Я реализовал простой 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)); }
}

на всякий случай, если он может быть вызван из другого потока?или ведущий имеет недостатки?

Любой совет приветствуется

1 Ответ

2 голосов
/ 15 ноября 2011

Да, вы должны это сделать.Я не знаю, какие другие библиотеки вы используете, но, вероятно, хорошей идеей будет добавить аспект для всех ваших представлений, чтобы сделать это для вас.

Также, возможно, стоит добавить пару дружественных методов вбазовый вид;Например, у меня есть эти:

    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();
    }

для примера проверки реализации аспекта здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...