使用后台工作程序单击了哪个按钮

时间:2015-08-21 09:39:22

标签: c# backgroundworker

我有几个按钮可以使用后台工作程序执行某些操作。我想知道点击了哪个按钮,所以我这样做了:

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的帮助下完成了这项工作,但我不知道如何处理这个问题。请帮忙。

2 个答案:

答案 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;

}