1

我愿意报告密集任务 (I/O) 的进度。我一直在阅读所有方法、界面、backGroundWorker、进度,但没有人包含任何类型的附加信息,例如任务的当前阶段。所以我写了这个方法,如果你能给我任何反馈、建议或评论,我会很高兴。我在一个 winforms 4.0 项目中工作。

这是任务

   class _ThreadTest
        {
        public static  void ReporteProgreso(out int p, out string stage)
        {
            p = 0;
            stage = "";
            for (int i = 0; i < 10; i++)
            {

                System.Threading.Thread.Sleep(500);
                p++;

                switch (p)
                {
                    case 0: stage = "init"; break;
                    case 1: stage = "Loading Data"; break;
                    case 2: stage = "Parsing Data"; break;
                    case 3: stage = "Checking"; break;
                    case 4: stage = "Inserting n Records"; break;
                    case 5: stage = "10%"; break;
                    case 6: stage = "50%"; break;
                    case 7: stage = "70%"; break;
                    case 8: stage = "100%"; break;
                    case 9: stage = "finish"; break;                        

                    default:
                        break;
                }
            }

        }
    }

这就是我所说的

  static void Main()
        {

        //Reportar progreson con OUT
        int p = 0;
        string stage = "";
        _ThreadTest t = new _ThreadTest();
        Thread oThread = new Thread( () => _ThreadTest.ReporteProgreso(out p,out stage) ) ;
        oThread.Start();

        int tmp = 0;
        while (oThread.IsAlive)
        {

            if (tmp != p)
            {
                Console.WriteLine(stage);
                tmp = p;
            }
        }

        Console.ReadKey();

    }
}

是否有任何有趣的测试,更好的方法来实现这一目标?由于这种方法对我有用,因此在某些类型的环境中使用可能不安全。

4

2 回答 2

2

BackgroundWorker.ReportProgress完全符合您的要求。第二个参数是一个包含自定义进度报告的对象。

第二个参数位于传递给事件处理程序的ProgressChangedEventArgsUserState的属性中。ProgressChanged

BackgroundWorker MSDN 主题有一个很好的例子。该示例中唯一缺少的是如何使用UserState. 它是一个对象,因此您需要对其进行投射。因此,如果您的ReportProgress电话是:

ReportProgress(1, "Loading data");

然后在您的ProgressChanged事件处理程序中,您将其转换回字符串:

// This event handler updates the progress. 
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    resultLabel.Text = (string)e.UserState
}
于 2013-08-22T15:54:42.423 回答
1

我找到了一种适合我需要的方法

在我昂贵的任务中,我用这样的东西处理他的舞台

public static class ExpensiveTasks
{
    public static IEnumerable<KeyValuePair<String, int>> ExpensiveTask1(int sleepTime)
    {
        for (int i = 1; i <= 100; i++)
        {
            System.Threading.Thread.Sleep(sleepTime);
            yield return new KeyValuePair<String, int>("Reporting Progress", i);
        }
    }
}

然后从调用它的方法中,使用类似这样的 BackGroundWorker DoWork Event

   void bW_DoWork(object sender, DoWorkEventArgs e)
    {            
        //var args = e.Argument;             
        BackgroundWorker _bw = sender as BackgroundWorker;

        foreach (var report in ExpensiveTasks.ExpensiveTask1(100))
        {
            if (_bw.CancellationPending == true)
            {
                e.Cancel = true;
                return;
            }
            _bw.ReportProgress(report.Value,report.Key);
        }
        e.Result = "The End";           
    }

通过这种方法,我可以维护我的分层结构,当然我可以以某种方式将 BWWorker 的引用发送到昂贵的任务,但也许它会在另一个层或模块下。所以至少用这种方式来做这件事,一直在为我工作。

:)

于 2013-10-01T05:04:56.867 回答