2013-08-31 1 views
0

Я не могу заставить фонового рабочего работать. Это мой первый раз, используя его, поэтому я не знаю, сделал ли я что-то не так. Вот мой код:Не могу получить backgoundworker для работы

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

Пожалуйста, помогите или сказать, если я делаю что-то неправильно, спасибо.

+0

Что не работает на вас? DoWork не выполняется или progres не уведомляется? – Kurubaran

+0

ничего, когда я нажимаю кнопку, ничего не происходит, когда она должна показывать диалог открытой папки. – outlaw1994

+2

Первое, что я могу вам сказать, это то, что вы определенно не должны пытаться показать форму внутри метода DoWork. Метод 'DoWork' работает в фоновом потоке, а не в потоке пользовательского интерфейса. –

ответ

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

причина, по которой я использую фоновый рабочий, для индикатора выполнения, поскольку прог преобразует большое количество данных в фотографии. – outlaw1994

1

Самая важная деталь вы упускать из виду, что вы есть сделать что-то разумное, когда работник бросил исключение. Как минимум, вы должны сообщить об этом в вашем RunWorkerCompleted обработчика событий:

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

Вы теперь также обнаружить проблему в коде, вы не можете использовать OpenFileDialog на рабочем потоке. Отобразите его на потоке пользовательского интерфейса, а затем , затем запустите работника, пройдя выбор.

И да, это отличается от того, к чему вы привыкли, вы ожидаете, что отладчик расскажет вам о необработанных исключениях. Это не работает одинаково, когда try/catch - это код обертывания, они встроены в класс BackgroundWorker. Вы можете заставить отладчик остановиться в таком невидимом исключении с помощью Debug + Exceptions, отметьте флажок «Бросок» для исключений CLR. Это не совсем повод пропустить проверку e.Error в обработчике событий.

+0

спасибо попробует это – outlaw1994

Смежные вопросы