【问题标题】:C# - Not all code paths return a valueC# - 并非所有代码路径都返回一个值
【发布时间】:2017-07-14 03:07:55
【问题描述】:

对不起,它与其他帖子相似,但我已经阅读了一个小时类似的帖子,并审查/重新审查了我的代码,但我只是看不出它没有返回值的地方。任何帮助表示赞赏。

public static bool UploadLog()
        {
            var uploader = new BackgroundWorker();
            uploader.DoWork += delegate (object sender, DoWorkEventArgs e)
            {
                Properties.Settings.Default.logUrl = "";
                Properties.Settings.Default.Save();

                System.Collections.Specialized.NameValueCollection Data = new System.Collections.Specialized.NameValueCollection();
                Data["api_paste_name"] = "RWC_Log_" + DateTime.Now.ToString() + ".log";
                Data["api_paste_expire_Date"] = "N";
                Data["api_paste_code"] = File.ReadAllText(Properties.Settings.Default.AppDataPath + @"\Logs\RWC.log");
                Data["api_dev_key"] = "017c00e3a11ee8c70499c1f4b6b933f0";
                Data["api_option"] = "paste";

                WebClient wb = Proxy.setProxy();

                try
                {
                    byte[] bytes = wb.UploadValues("http://pastebin.com/api/api_post.php", Data);
                    string response;
                    using (MemoryStream ms = new MemoryStream(bytes))
                    using (StreamReader reader = new StreamReader(ms))
                        response = reader.ReadToEnd();

                    if (response.StartsWith("Bad API request"))
                    {
                        Logging.LogMessageToFile("Failed to upload log to Pastebin: " + response);
                        e.Result = false;
                    }
                    else 
                    {
                        Logging.LogMessageToFile("Logfile successfully uploaded to Pastebin: " + response);
                        Properties.Settings.Default.logUrl = response;
                        Properties.Settings.Default.Save();
                        e.Result = true;
                    }
                }
                catch (Exception ex)
                {
                    Logging.LogMessageToFile("Error uploading logfile to Pastebin: " + ex.Message);
                    e.Result = false;
                }
            };
            uploader.RunWorkerAsync();
        }

编辑:我已经尝试以async 运行此函数,但它导致 UI 锁定,因此在后台工作程序中运行此函数。

【问题讨论】:

  • 紧跟在uploader.RunWorkerAsync();之后,没有返回值。
  • Not all code paths return a value 我想你会发现这里实际上有没有个返回值的代码路径。
  • Abion47 完全正确:)
  • 你的方法声明声明了一个布尔返回值。 public static bool UploadLog(),因此,您的所有代码路径都必须返回一个 bool。通过代码路径......您方法的所有“退出点”都必须返回一个值。除非您将“bool”更改为“void”,这仅意味着您的方法不会返回值。
  • 从设计的角度来看,无论如何您都应该将方法更改为void。我对您尝试做的事情的理解是返回异步过程是否成功完成。但是,为了做到这一点,您必须等待该过程完成,这违背了异步调用它的目的。相反,您应该完全忽略工作人员并让它做自己的事情,然后使用worker.RunWorkerCompleted 事件检查它是否成功完成。

标签: c# winforms boolean backgroundworker


【解决方案1】:

对于返回bool 的函数(参见函数定义),您必须至少在代码中的某处返回一个。在uploader.RunWorkerAsync (); 之后添加return true;。这将完成这项工作。

更好的可能性是使函数async 或使用void 作为返回类型。

【讨论】:

  • 这是有道理的,至少对于上面的代码。不依赖于布尔值,所以true 可以。函数的 void 返回类型将是更好的选择,我已经更新了我的答案。
  • 不,这没有意义。如果不管发生什么你都要返回true,那么方法应该是void
  • 这正是我所说的。
  • 没有必要用你的第一行屈尊于 OP。你说你已经阅读了一个小时的类似帖子,但你的代码中仍然没有一个 return 语句。 .. 你和我都知道 OP 是否说真话.. 所以不要假设他们在撒谎并为此而放下他们。这应该是一个支持性的社区。​​span>
  • @Rawns 如果你让你的函数异步并且它锁定了 UI,那么你在某个地方搞砸了。我建议再试一次,因为使用异步函数可以更好地处理异步进程。
【解决方案2】:

你的方法声明声明了一个 bool 返回值。 public static bool UploadLog(),因此,您的所有代码路径都必须返回一个布尔值。通过代码路径......您方法的所有“退出点”都必须返回一个值。除非您将“bool”更改为“void”,这仅意味着您的方法不会返回值。

    /// <summary>
    /// With return bool
    /// </summary>
    /// <returns></returns>
    public static bool UploadLog()
    {
        var didItWork = true;//here's a return value you could use. Initialize to true

        var uploader = new BackgroundWorker();
        uploader.DoWork += delegate (object sender, DoWorkEventArgs e)
        {
            Properties.Settings.Default.logUrl = "";
            Properties.Settings.Default.Save();

            System.Collections.Specialized.NameValueCollection Data = new System.Collections.Specialized.NameValueCollection();
            Data["api_paste_name"] = "RWC_Log_" + DateTime.Now.ToString() + ".log";
            Data["api_paste_expire_Date"] = "N";
            Data["api_paste_code"] = File.ReadAllText(Properties.Settings.Default.AppDataPath + @"\Logs\RWC.log");
            Data["api_dev_key"] = "017c00e3a11ee8c70499c1f4b6b933f0";
            Data["api_option"] = "paste";

            WebClient wb = Proxy.setProxy();

            try
            {
                byte[] bytes = wb.UploadValues("http://pastebin.com/api/api_post.php", Data);
                string response;
                using (MemoryStream ms = new MemoryStream(bytes))
                using (StreamReader reader = new StreamReader(ms))
                    response = reader.ReadToEnd();

                if (response.StartsWith("Bad API request"))
                {
                    Logging.LogMessageToFile("Failed to upload log to Pastebin: " + response);
                    e.Result = false;
                }
                else
                {
                    Logging.LogMessageToFile("Logfile successfully uploaded to Pastebin: " + response);
                    Properties.Settings.Default.logUrl = response;
                    Properties.Settings.Default.Save();
                    e.Result = true;
                }
            }
            catch (Exception ex)
            {
                Logging.LogMessageToFile("Error uploading logfile to Pastebin: " + ex.Message);
                e.Result = false;
                didItWork = false;//did not work, so set the return value accordingly
            }
        };
        uploader.RunWorkerAsync();

        return didItWork;//return the result

    }

    /// <summary>
    /// Drop the return value by making it void instead of bool
    /// </summary>
    public static void UploadLog()
    {
        var uploader = new BackgroundWorker();
        uploader.DoWork += delegate (object sender, DoWorkEventArgs e)
        {
            Properties.Settings.Default.logUrl = "";
            Properties.Settings.Default.Save();

            System.Collections.Specialized.NameValueCollection Data = new System.Collections.Specialized.NameValueCollection();
            Data["api_paste_name"] = "RWC_Log_" + DateTime.Now.ToString() + ".log";
            Data["api_paste_expire_Date"] = "N";
            Data["api_paste_code"] = File.ReadAllText(Properties.Settings.Default.AppDataPath + @"\Logs\RWC.log");
            Data["api_dev_key"] = "017c00e3a11ee8c70499c1f4b6b933f0";
            Data["api_option"] = "paste";

            WebClient wb = Proxy.setProxy();

            try
            {
                byte[] bytes = wb.UploadValues("http://pastebin.com/api/api_post.php", Data);
                string response;
                using (MemoryStream ms = new MemoryStream(bytes))
                using (StreamReader reader = new StreamReader(ms))
                    response = reader.ReadToEnd();

                if (response.StartsWith("Bad API request"))
                {
                    Logging.LogMessageToFile("Failed to upload log to Pastebin: " + response);
                    e.Result = false;
                }
                else
                {
                    Logging.LogMessageToFile("Logfile successfully uploaded to Pastebin: " + response);
                    Properties.Settings.Default.logUrl = response;
                    Properties.Settings.Default.Save();
                    e.Result = true;
                }
            }
            catch (Exception ex)
            {
                Logging.LogMessageToFile("Error uploading logfile to Pastebin: " + ex.Message);
                e.Result = false;
                didItWork = false;//did not work, so set the return value accordingly
            }
        };
        uploader.RunWorkerAsync();
    }

【讨论】:

  • 我想指出的是,无论工作线程的结果如何,第一个选项几乎总是每次都返回 true,因为工作线程可能甚至没有时间启动(更不用说得到在主线程返回didItWork 的值时执行到完成点。
  • 感谢您的指点。我想我现在可以看到我可能走错了路,不想为最终用户锁定 UI,同时又想等待成功或失败的失败结果。
【解决方案3】:

一些 cmets 指出使用 async 而不是后台工作人员。我对此进行了更多阅读并重新访问了我的代码,它现在可以成功运行,并且也没有锁定 UI。 :)

我现在工作的代码:

public static async Task<bool> UploadLog()
        {
            Properties.Settings.Default.logUrl = "";
            Properties.Settings.Default.Save();

            System.Collections.Specialized.NameValueCollection Data = new System.Collections.Specialized.NameValueCollection();
            Data["api_paste_name"] = "RWC_Log_" + DateTime.Now.ToString() + ".log";
            Data["api_paste_expire_Date"] = "N";
            Data["api_paste_code"] = File.ReadAllText(Properties.Settings.Default.AppDataPath + @"\Logs\RWC.log");
            Data["api_dev_key"] = "017c00e3a11ee8c70499c1f4b6b933f0";
            Data["api_option"] = "paste";

            WebClient wb = Proxy.setProxy();

            try
            {
                byte[] bytes = wb.UploadValues("http://pastebin.com/api/api_post.php", Data);
                string response;
                using (MemoryStream ms = new MemoryStream(bytes))
                using (StreamReader reader = new StreamReader(ms))
                    response = reader.ReadToEnd();

                if (response.StartsWith("Bad API request"))
                {
                    Logging.LogMessageToFile("Failed to upload log to Pastebin: " + response);
                    return false;

                }
                else 
                {
                    Logging.LogMessageToFile("Logfile successfully uploaded to Pastebin: " + response);
                    Properties.Settings.Default.logUrl = response;
                    Properties.Settings.Default.Save();
                    return true;

                }
            }
            catch (Exception ex)
            {
                Logging.LogMessageToFile("Error uploading logfile to Pastebin: " + ex.Message);
                return true;

            }
        }

我的按钮调用代码:

private async void btnUpload_Click(object sender, EventArgs e)
        {
            this.btnUpload.Enabled = false;
            this.btnUpload.Text = "Uploading...";

            var uploaded = await Task.Run(Pastebin.UploadLog);

            this.btnUpload.Text = "Upload";
            this.btnUpload.Enabled = true;

            if (uploaded == true)
            {
                Clipboard.SetText(Properties.Settings.Default.logUrl);
                MessageBox.Show("Your logfile has been uploaded to Pastebin successfully.\r\n" +
                    "The URL to the Paste has been copied to your clipboard.", "Upload successful!", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("The upload of your logfile to Pastebin failed.", "Upload failed!", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    相关资源
    最近更新 更多