c#委托进度条多线程和类中的类

时间:2014-12-17 09:27:06

标签: c# multithreading winforms delegates

我得到了使用B类和B类的Winform(A类) B类使用C类

C类为我做的事情是读取word文档并检索数据并将其粘贴到excel文件中。 我为此做了一个单独的线程,所以我仍然可以移动winform。

现在我希望我的进度条能够查看它正在处理的文件的值,从0到amountoffiles。

只有在表单为活动窗口时才会更新。

我目前在C组中得到了这个。我将progressBar作为参数从A类到B到C。

private void SetValue(int value)
{
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.
    try
    {
        if (this.pbar.InvokeRequired)
        {
            if (Doc_converter.Form1.ActiveForm != null)
            {
                SetTextCallback d = new SetTextCallback(SetValue);
                Doc_converter.Form1.ActiveForm.Invoke(d, new object[] { value });
            }
        }
        else
        {
            this.pbar.Value = value;
        }
    }
    catch
    {
        //To do
    }
}

delegate void SetTextCallback(int value);

有没有不同的方法来完成这项工作?

或从C级到A级的代表?

请记住,它与表单线程不同。

编辑:忘记提到我只能使用.NET 4.0或更低版本,因为应用程序必须在Windows XP机器上运行。

1 个答案:

答案 0 :(得分:0)

在.NET 4.5或带有Microsoft.Bcl.Async包的.NET 4.0中,您可以使用Progress类将进度消息(实际上是完整的对象)从一个线程发送到另一个线程。在创建初始Progress对象的线程上(特别是在发生对象创建的SynchronizationContext上)引发事件,因此您根本不需要使用Invoke

您应该在UI线程上创建一个Progress对象,并将其作为IProgress接口传递给后台处理类。每次后台线程调用Report时,将在表单中调用相应的回调,例如:

在表格上:

private void ReportProgress(Tuple<int,string> progress)
{        
    pbar.Value=progress.Item1;
    status.Text=progress.Item2;
}


public void StartProcessing()
{
    IProgress<Tuple<int,string>> progress=new Progress<Tuple<int,string>>(ReportProgress);

    var workerClass=new MyWorkerClass();
    workerClass.DoWork(progress);
    ....
}

在工人阶级:

public void DoWork(IProgress<Tuple<int,string> progress)
{
    for (int i=0;i++;i<1000)
    {
         if (i%10==0)
         {
             progress.Report(Tuple.Create(i/10,String.Format("Now at {0}",i);
         }
    }
}

这个例子当然是人为的,我可以使用Progress<int>代替Progress<Tuple<int,string>>,但这表明Progress对象可以将复杂对象作为消息发送,而不仅仅是整数。

Progress作为IProgress接口传递是必需的,因为Progress明确实现了IProgress.Report。通过这种方式,即使您想懒惰地将Progress传递给工作人员,也无法依赖于特定的实现