C# - 使用后台工作者从另一个 class 返回布尔响应

C# - Returning a bool response from another class using background worker

我有一个带有按钮的 WinForm,单击该按钮会调用另一个 class 中的方法以将文本文件上传到 Pastebin。代码最初工作正常但锁定 UI 直到上传成功完成,所以我现在尝试使用后台工作人员完成此任务,以便 UI 保持响应。

我在 Visual Studio 中遇到的错误是 Anonymous function converted to a void returning delegate cannot return a value。我看过类似的 threads/google 但不太明白这意味着什么以及如何纠正它。

我的上传按钮代码:

private void btnUpload_Click(object sender, EventArgs e)
{
    this.btnUpload.Enabled = false;
    this.btnUpload.Text = "Uploading...";
    if (Pastebin.UploadLog())
    {
        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);
    }
    this.btnUpload.Text = "Upload";
    this.btnUpload.Enabled = true;
}

我完成上传的代码:

class Pastebin
    {
        public static bool UploadLog()
        {
            var upload = new BackgroundWorker();
            upload.DoWork += delegate
            { 
                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 false;
                }
            };

            upload.RunWorkerAsync();

        }
    }

我建议您使用 async 函数而不是 BackgroundWorker。您可以使 UploadLog 函数 async 如下所示。

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 false;
            }

    }

然后您可以像这样调用您的 async 函数。

private async void btnUpload_Click(object sender, EventArgs e)
{
this.btnUpload.Enabled = false;
this.btnUpload.Text = "Uploading...";
var result = await Pastebin.UploadLog();
if (result)
{
    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);
}
this.btnUpload.Text = "Upload";
this.btnUpload.Enabled = true;
}