我无法让后台工作人员上班。这是我第一次使用它,所以我不知道我做错了什么。这是我的代码:
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 :(得分: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);
}
}
}
答案 1 :(得分:1)
您忽略的最重要的细节是,当工作人员抛出异常时,您有做一些合理的事情。至少,您必须在RunWorkerCompleted事件处理程序中报告它:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Error != null) {
MessageBox.Show(e.Error.ToString());
}
else {
// etc..
}
}
您现在还将在代码中发现问题,不能在工作线程上使用OpenFileDialog。在UI线程上显示它,然后然后启动worker,传递选择。
是的,这与您习惯的不同,您希望调试器告诉您未处理的异常。当try / catch包装代码时,它的工作方式不同,它们内置在BackgroundWorker类中。您可以使用Debug + Exceptions让调试器停在这样一个不可见的异常中,勾选CLR异常的Thrown复选框。这不是跳过事件处理程序中的e.Error检查的理由。