简体   繁体   English

无法让backgoundworker工作

[英]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 . 如果你真的需要从后台线程调用ShowDialog,你需要使用Invoke送对前台线程的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. 您从未解释过为什么您首先使用BackgroundWorker。 Why can't you start up the BackgroundWorker after you've shown the folder browser dialog? 在显示文件夹浏览器对话框后,为什么不能启动BackgroundWorker? 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: 至少,您必须在RunWorkerCompleted事件处理程序中报告它:

    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. 您现在还将在代码中发现问题,不能在工作线程上使用OpenFileDialog。 Display it on the UI thread instead and then start the worker, passing the selection. 而是在UI线程上显示它, 然后启动worker,传递选择。

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. 当try / catch包装代码时,它的工作方式不同,它们内置在BackgroundWorker类中。 You can get the debugger to stop at such an invisible exception with Debug + Exceptions, tick the Thrown checkbox for CLR exceptions. 您可以使用Debug + Exceptions让调试器停在这样一个不可见的异常中,勾选CLR异常的Thrown复选框。 This is not otherwise a good reason to skip the e.Error check in the event handler. 这不是跳过事件处理程序中的e.Error检查的理由。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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