通过ref值传递函数的进度是个好主意吗

本文关键字:好主意 ref 传递函数 通过 | 更新日期: 2023-09-27 18:20:04

几天前,我问了一个关于如何不断检查函数进度的问题,但我没有得到任何答案,所以我试图找到一种方法来完成它,所以我在函数中引用了参数,它们会返回我要处理的项目总数和当前处理的项目

public void SaveInfoToDBFromFiles(string path,ref int TotalItems, ref int CurrentItem)
{
  initialize the values;
  do some stuff;
  TotalItems=TotalNumberOfFiles;
  foreach(file in path)
  {
   CurrentItem++;
  } 
}

在我的UI winforms中,我创建了一个线程,我有一个进度条,它向我显示函数的当前进度,还有一个计时器,它通过获取CurrentItem值来更新进度条

        System.Threading.Thread th = new System.Threading.Thread(() =>   SaveInfoToDBFromFiles(path,ref Total,ref  Current));
        th.Start();
        progressBar1.Value=Total;
        timer1.Start();


    private void timer1_Tick(object sender, EventArgs e)
    {
        progressBar1.Value = Current;
    }

它运行得很好,但我想知道这是否是个好主意?

通过ref值传递函数的进度是个好主意吗

现在你可以用一种更好的方式来做这件事。

您可以使用Progress<T>类,并让框架将其封送回您的UI线程中。

有点像这样:

var progress = new Progress<int>(currentItem =>
{
    progressBar1.Value = currentItem;
});
await Task.Run(() => SaveInfoToDBFromFiles(path, progress);

然后你可以只报告保存方法的进度:

public void SaveInfoToDBFromFiles(string path, IProgress<int> progress) {
    // .. other code here ..
    var i = 0;
    foreach (var file in path) {
        progress.Report(i);
        i++;
    }
}

你甚至可以包装一个包含更多信息的自定义类型:

// first, a class to hold it all
class MyType {
    public string FileName { get; set; }
    public int CurrentItem { get; set; }
}
// .. then you need to declare the Progress instance to hold your type
var progress = new Progress<MyType>(myType => 
{
    label1.Text = myType.FileName;
    progressBar1.Value = myType.CurrentItem;
});
// then when you're reporting progress you pass an instance of your type
progress.Report(new MyType {
    FileName = file,
    CurrentItem = i
});