0

我无法让后台工作人员工作。这是我第一次使用它,所以我不知道我是否做错了什么。这是我的代码:

    int cardcount = 0;
    string lev = "";
    string att = "";
    string atk = "";
    string def = "";
    string ctp = "";
    string id = "";
    void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            string folder = folderBrowserDialog1.SelectedPath;
            DirectoryInfo dinfo = new DirectoryInfo(folderBrowserDialog1.SelectedPath);
            FileInfo[] Files = dinfo.GetFiles("*.jpg");
            int count = Files.Length;
            int current = 0;

            foreach (FileInfo file in Files)
            {
                string path = Path.GetFileNameWithoutExtension(file.Name);
                int cardid = Convert.ToInt32(path);
                if (Program.CardData.ContainsKey(cardid))
                {
                    DevPro_CardManager.cardmaker.IMG = LoadBitmap(folderBrowserDialog1.SelectedPath + "//" + file.Name);
                    id = Program.CardData[cardid].Id.ToString();
                    lev = Program.CardData[cardid].Level.ToString();
                    att = Program.CardData[cardid].Attribute.ToString();
                    if (att == "1")
                    {
                        att = "earth";
                    }
                    else if (att == "2")
                    {
                        att = "water";
                    }
                    else if (att == "4")
                    {
                        att = "fire";
                    }
                    else if (att == "8")
                    {
                        att = "wind";
                    }
                    else if (att == "16")
                    {
                        att = "light";
                    }
                    else if (att == "32")
                    {
                        att = "dark";
                    }
                    else if (att == "64")
                    {
                        att = "divine";
                    }
                    if (Program.CardData[cardid].Atk.ToString() == "-2")
                    {
                        atk = "????";
                    }
                    else
                    {
                        atk = Program.CardData[cardid].Atk.ToString();
                    }
                    if (Program.CardData[cardid].Def.ToString() == "-2")
                    {
                        def = "????";
                    }
                    else
                    {
                        def = Program.CardData[cardid].Def.ToString();
                    }
                    ctp = Program.CardData[cardid].Type.ToString();
                    if (ctp == "2" || ctp == "130" || ctp == "65538" || ctp == "131074" || ctp == "262146" || ctp == "524290")
                    {
                        ctp = "spell";
                    }
                    else if (ctp == "4" || ctp == "1048580" || ctp == "131076")
                    {
                        ctp = "trap";
                    }
                    else if (ctp == "129" || ctp == "161")
                    {
                        ctp = "ritual";
                    }
                    else if (ctp == "65" || ctp == "97")
                    {
                        ctp = "fusion";
                    }
                    else if (ctp == "8193" || ctp == "8225" || ctp == "12321")
                    {
                        ctp = "synchro";
                    }
                    else if (ctp == "8388609" || ctp == "8388641")
                    {
                        ctp = "xyz";
                    }
                    else if (ctp == "33" || ctp == "545" || ctp == "1057" || ctp == "2081" || ctp == "4129" || ctp == "4194337")
                    {
                        ctp = "effect";
                    }
                    else if (ctp == "17" || ctp == "4113")
                    {
                        ctp = "normal";
                    }
                    else if (ctp == "16401")
                    {
                        ctp = "token";
                    }
                    cardcount = cardcount + 1;
                    backgroundWorker1.ReportProgress((current * 100) / count);
                }
            }
        }
    }
    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // The progress percentage is a property of e
        progressBar1.Value = e.ProgressPercentage;
        label8.Text = cardcount.ToString();
        comboBox2.SelectedItem = lev;
        comboBox1.SelectedItem = att;
        textBox2.Text = atk;
        textBox1.Text = def;
        comboBox3.SelectedItem = ctp;
        GenerateCard();
        ImageResizer.CropImage(361, 523, pictureBox1.Image, @"anime cards\" + Path.GetFileName(id));
    }

以及启动它的按钮的代码:

 private void button5_Click(object sender, EventArgs e)
    {       
            backgroundWorker1.RunWorkerAsync();
    }

如果我做错了什么,请帮忙或说,谢谢。

4

2 回答 2

1

您忽略的最重要的细节是,当工作人员抛出异常时,您必须做一些合理的事情。至少,您必须在 RunWorkerCompleted 事件处理程序中报告它:

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        if (e.Error != null) {
            MessageBox.Show(e.Error.ToString());
        }
        else {
            // etc..
        }
    }

您现在还将发现代码中的问题,您不能在工作线程上使用 OpenFileDialog。而是在 UI 线程上显示它,然后启动工作程序,传递选择。

是的,这与您习惯的不同,您希望调试器告诉您未处理的异常。当 try/catch 包装代码时,这不会以相同的方式工作,它们内置在 BackgroundWorker 类中。您可以使用 Debug + Exceptions 让调试器在这种不可见的异常处停止,勾选 CLR 异常的 Thrown 复选框。这不是跳过事件处理程序中的 e.Error 检查的好理由。

于 2013-08-31T11:23:34.427 回答
1

如果您确实需要从后台线程调用 ShowDialog,则需要使用Invoke. 以下是您可以如何执行此操作的示例:

public partial class Form1 : Form
{
    private delegate DialogResult ShowFolderBrowser();

    public Form1()
    {
        InitializeComponent();
    }

    private DialogResult ShowFolderBrowserDialog()
    {
        return this.folderBrowserDialog1.ShowDialog();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        if ((DialogResult)this.Invoke(this.ShowFolderBrowserDialog) == DialogResult.OK)
        {
            // ...
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync();
    }
}

但是,我建议您重新考虑您的设计。你从来没有解释过为什么你首先要使用 BackgroundWorker。为什么在显示文件夹浏览器对话框后无法启动 BackgroundWorker ?像这样:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        string folder = e.Argument as string;
        // ...
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
        {
            string folder = this.folderBrowserDialog1.SelectedPath;
            this.backgroundWorker1.RunWorkerAsync(folder);
        }
    }
}
于 2013-08-31T08:41:26.500 回答