我有几个按钮可以使用后台工作程序执行某些操作。我想知道点击了哪个按钮,所以我这样做了:
public MyClass()
{
_worker.DoWork += worker_DoWork;
_worker.RunWorkerCompleted += worker_RunWorkerCompleted;
_worker.ProgressChanged += worker_ProgressChanged;
_worker.WorkerReportsProgress = true;
}
private void First_Button_Click(object sender, RoutedEventArgs e)
{
_worker.RunWorkerAsync();
}
private void Second_Button_Click(object sender, RoutedEventArgs e)
{
_worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
Button clickedButton = (Button)sender;
switch (clickedButton.Name)
{
case "First_Button":
directory = _ftp.GetCurrentDate(true);
break;
case "Second_Button":
directory = _ftp.GetCurrentDate(false);
break;
case null:
return;
}
}
当我点击其中一个按钮时,我得到System.InvalidCastException: Unable to cast object of type 'System.ComponentModel.BackgroundWorker' to type 'System.Windows.Controls.Button' .
我知道线程安全调用的重要性,之前我已经在this site的帮助下完成了这项工作,但我不知道如何处理这个问题。请帮忙。
答案 0 :(得分:3)
sender
参数是引发事件的对象,因此在您的情况下,它将是BackgroundWorker
对象,而不是Button
。这就是演员阵容失败的原因。
您可以使用接受对象的重载将按钮名称传递给后台工作程序。然后可以在DoWork
事件中使用它。
例如:
private void First_Button_Click(object sender, RoutedEventArgs e)
{
_worker.RunWorkerAsync("First_Button");
}
private void Second_Button_Click(object sender, RoutedEventArgs e)
{
_worker.RunWorkerAsync("Second_Button");
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string buttonName = (string)e.Argument;
switch (buttonName)
{
case "First_Button":
directory = _ftp.GetCurrentDate(true);
break;
case "Second_Button":
directory = _ftp.GetCurrentDate(false);
break;
case null:
return;
}
}
考虑到这一点,我总觉得为背景工作者参数创建一个专用类是个好主意,这样你就可以根据需要轻松传递多个值。
答案 1 :(得分:0)
这是否与您想要执行的内容更接近?
public Form1()
{
InitializeComponent();
Second_Button.Click += ButtonClick;
First_Button.Click += ButtonClick;
}
private void ButtonClick(object sender, EventArgs e)
{
var directory = String.Empty;
Button clickedButton = (Button)sender;
switch (clickedButton.Name)
{
case "First_Button":
directory = _ftp.GetCurrentDate(true);
break;
case "Second_Button":
directory = _ftp.GetCurrentDate(false);
break;
case null:
return;
}
First_Button.Enabled = false;
Second_Button.Enabled = false;
var bw = new BackgroundWorker();
bw.DoWork += (o, args) =>
{
// your work. You can use directory here
};
bw.RunWorkerCompleted += (o, args) =>
{
First_Button.Enabled = true;
Second_Button.Enabled = true;
};
bw.RunWorkerAsync();
}
或者甚至更好:
private async void ButtonClick(object sender, EventArgs e)
{
var directory = String.Empty;
Button clickedButton = (Button)sender;
switch (clickedButton.Name)
{
case "First_Button":
directory = _ftp.GetCurrentDate(true);
break;
case "Second_Button":
directory = _ftp.GetCurrentDate(false);
break;
case null:
return;
}
First_Button.Enabled = false;
Second_Button.Enabled = false;
await Task.Run(() =>
{
// your work. you can use directory here
});
First_Button.Enabled = true;
Second_Button.Enabled = true;
}