【问题标题】:Values "resetting" back to zero after Task is completed C#任务完成后将值“重置”回零 C#
【发布时间】:2016-06-02 09:43:55
【问题描述】:

这是我的函数,它返回一个结构,其中包含成功命令的数量、错误的数量以及总数 以及它们在 Iprogress 界面中执行的文件路径。

   public void ExecuteCommands(string Directories, CdpsiUpdateSql Updater, CdpsiUpdateSqlparser parser, string Log, IProgress<Result> progress)
        {
            Result FinalResult = new Result();
            int totalWithErrors = 0;
            int totalSuccess = 0;
            string[] numArray1 = new string[3];
            List<string> list = ((IEnumerable<string>)Directory.GetFiles(Directories, "*.sql", SearchOption.TopDirectoryOnly)).Select(f =>
            {
                string[] strArray = Path.GetFileName(f).Split('_');
                int result;
                if (strArray.Length < 1 || !int.TryParse(strArray[0], out result))
                    result = -1;
                var data = new
                {
                    File = f,
                    Version = result
                };
                return data;
            }).Where(f => f.Version > -1).OrderBy(f => f.Version).Select(f => f.File).ToList<string>();
            foreach (string str in list)
            {
                int[] numArray2 = this.ExecuteCommand(parser.Parser(str), Updater, str, Log);
                int Succcesses = numArray2[0];
                int Errors = numArray2[1];
                //totalWithErrors += Errors;
                //totalSuccess += Succcesses;

                FinalResult.File = str;
                FinalResult.Errors = Errors;
                FinalResult.Successes = Errors;
                //FinalResult.TotalWithErrors = totalWithErrors;
                //FinalResult.totalSuccess = totalSuccess;


                progress.Report(FinalResult);
            }
        }

在我的主代码中,我这样调用函数:

foreach (var ConnectionString in ConnectionStrings)
        {
            connection = new OracleConnection(ConnectionString);
            using (CdpsiUpdateSql NewUpdater = new CdpsiUpdateSql(connection))
            {
                labelBDver.Text = Global.VersaoBd = NewUpdater.LookUp("GGDSC", "APPLCONFIG", "GGCOD = 'APP_NAME'");
                lbVersao.Text = "Versão: " + Global.NovaVersao;
                CpdisUpdateScripts Scripts = new CpdisUpdateScripts();
                CdpsiUpdateSqlparser Parser = new CdpsiUpdateSqlparser();
                var progressHandler = new Progress<CpdisUpdateScripts.Result>(result =>
                {
                    textBox1.Text = result.File;
                    //Global.TotalExecCerros = result.TotalWithErrors;
                    //Global.TotalExecSuccessfull = result.totalSuccess;
                    Global.TotalExecCerros += result.Errors;
                    Global.TotalExecSuccessfull += result.Successes;
                    labelErrorCommandCnt.Text = result.Errors.ToString();
                    labelSuccessfulCnt.Text = result.Successes.ToString();
                    Refresh();

                });
                IProgress<CpdisUpdateScripts.Result> progress = progressHandler;
                Task MyTask = Task.Run(() =>
                {

                    Scripts.ExecuteCommands(Global.Update + @"\scripts", NewUpdater, Parser,
                        Global.Update + @"\scripts", progress);

                });

            }
        }

在处理程序上,传递给标签的值是正确的,标签接收正确的值并且 Global.Cerros 和 Global.TotalExecSuccessfull = result.totalSuccess;也收到正确数量的错误,但是当 foreach 完成时,两者都是 0。 我不明白为什么会这样。

【问题讨论】:

  • 使任何你想要永久保持值的 varublw 保持静态或将其保存到 gui 并每次读取它的 baxk
  • 真的,你问的不是很清楚。这需要minimal reproducible example。您最好的选择是使用调试器逐步检查以找出错误设置为错误值的位置。顺便说一句,如果您只是阻止并等待它,那么您的Task.Run 是毫无意义的。
  • @CharlesMager 我刚刚添加了等待,看看它是否会改变任何东西,任务工作正常并且做我真正需要的,只是在它执行后值会变为 0,我ts 那我没有得到“为什么”我问为什么全球的价值。当 foreach 结束时,vars 回到 0。他们得到正确的值但回到 0 是没有意义的
  • @Shon 变量在这样声明的类中:public static int TotalExecCerros { get; set; } public static int TotalExecSuccessfull { get; set; }
  • @LikeIfYouCaredAboutMyName 目前尚不清楚哪些“值”被设置为零以及在哪里设置,更不用说为什么了,因此请求minimal reproducible example。虽然我怀疑在尝试创建一个时您可能会发现问题所在。

标签: c# variables task handler


【解决方案1】:

您的问题在于您的IProgress.Report(FinalResult)。每次将 Result 对象传递给IProgress.Report 方法时,都需要创建一个新副本。

所以要解决你的问题,你需要改变你的代码如下:

public void ExecuteCommands(string Directories, CdpsiUpdateSql Updater, CdpsiUpdateSqlparser parser, string Log, IProgress<Result> progress)
{
    //Remove this line
    //Result FinalResult = new Result();

    //... your code as is... bla bla bla

    foreach (string str in list)
    {
        int[] numArray2 = this.ExecuteCommand(parser.Parser(str), Updater, str, Log);
        int Succcesses = numArray2[0];
        int Errors = numArray2[1];

        //new line
        Result FinalResult = new Result();
        FinalResult.File = str;
        FinalResult.Errors = Errors;
        FinalResult.Successes = Errors;

        progress.Report(FinalResult);

    }
}

【讨论】:

  • 同样的问题,标签已正确更新,变量也是如此,但它们是 IDK 发生了什么,但它们的值设置为 0。也许我的处理程序中有什么东西?我真的不知道的事情。
  • 你在 Refresh() 方法中做了什么?顺便说一句,我在您的代码中注意到您有 FinalResult.Successes = Errors,这是故意的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多