使用后台工作器点击哪个按钮

本文关键字:按钮 后台 工作 | 更新日期: 2023-09-27 18:09:00

我有几个按钮做一些事情使用后台工作者。我想知道哪个按钮被点击了,所以我这样做:

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' .

我知道线程安全调用的重要性,我以前在这个网站的帮助下做过,但我不知道如何处理这个问题。请帮助。

使用后台工作器点击哪个按钮

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

只是为了思考,我总是发现为后台工作者参数创建一个专门的类是一个好主意,这样你可以很容易地传递多个值,如果需要

这是否更接近您想要执行的操作?

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