在一个用户界面中管理任务进度

本文关键字:管理任务 用户界面 一个 | 更新日期: 2023-09-27 18:13:44

我有一个应用程序,用户可以启动任务,繁重的任务。我想在一个用户界面网格(每一行是一个任务,有一个进度条)中管理这些任务的进度,用户可以通过单击按钮(使用主线程)来显示这个网格。我遇到的问题是一个跨线程操作。我知道为什么:每当任务进程改变时(使用thread1),算法就会尝试更新网格数据源(使用主线程)。但是我不知道如何修理它。

我的grid的DataSource属性被设置为一个BindingList<BackgroundOperation>

我的任务(BackgroundOperation)的定义

public class BackgroundOperation
{
    public int progression;
    public int Progression
    {
        get { return progression;}
        set
        {
            progression = value;
            OnPropertyChanged("Progression");
        }
    }
    public event EventHandler OnRun;
    public event EventHandler<ProgressChangedEventArgs> OnProgressChanged;
    public event PropertyChangedEventHandler PropertyChanged;
    public void Run()
    {
        var task = new Task(() =>
        {
            if (OnRun != null)
                OnRun(this, null);
        });
    task.Start();
    }
    public void ReportProgress(int progression)
    {
        Progression = progression;
        if (OnProgressChanged != null)
            OnProgressChanged(this, new ProgressChangedEventArgs { Progression = progression });
    }

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

在一个用户界面中管理任务进度

您需要在UI线程上运行OnProgressChanged(顺便说一句,应该只称为ProgressChanged)。您可以在创建类时保存当前的SynchronizationContext,然后在那里创建委托Post():

public class BackgroundOperation
{
    private readonly SynchronizationContext m_synchronizationContext;
    public BackgroundOperation()
    {
        m_synchronizationContext = SynchronizationContext.Current;
    }
    …
    public void ReportProgress(int progression)
    {
        Progression = progression;
        var handler = OnProgressChanged;
        if (handler != null)
            m_synchronizationContext.Post(
                _ => handler(
                    this,
                    new ProgressChangedEventArgs { Progression = progression }),
                null);
    }
}