简体   繁体   中英

Can't get backgoundworker to work

I can't get background worker to work. This is my first time using it so I don't know if I have done something wrong. Here's my code:

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

And the code for the button that launches it:

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

Please help or say if I'm doing something wrong, thanks.

If you really need to call ShowDialog from the background thread you will need to marshal the call to the foreground thread using Invoke . Here's an example of how you might do this:

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();
    }
}

However, I would recommend that you rethink your design somewhat. You never explained why you're using a BackgroundWorker in the first place. Why can't you start up the BackgroundWorker after you've shown the folder browser dialog? Like this:

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

The most important detail you overlooked is that you have to do something reasonable when the worker threw an exception. At a minimum, you'll have to report it in your RunWorkerCompleted event handler:

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

You will now also discover the problem in your code, you cannot use OpenFileDialog on a worker thread. Display it on the UI thread instead and then start the worker, passing the selection.

And yes, this is different from what you are used to, you expect the debugger to tell you about unhandled exceptions. That doesn't work the same way when a try/catch is wrapping code, they are built into the BackgroundWorker class. You can get the debugger to stop at such an invisible exception with Debug + Exceptions, tick the Thrown checkbox for CLR exceptions. This is not otherwise a good reason to skip the e.Error check in the event handler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM