C# 在另一个线程中运行任务,然后向主线程报告
我使用多个按钮的用户界面,我需要在点击按钮时启动后台任务,并在任务完成后向主线程+更新用户界面报告 这是我当前代码的一部分:C# 在另一个线程中运行任务,然后向主线程报告,c#,multithreading,user-interface,C#,Multithreading,User Interface,我使用多个按钮的用户界面,我需要在点击按钮时启动后台任务,并在任务完成后向主线程+更新用户界面报告 这是我当前代码的一部分: private void button1Click(object sender, EventArgs e) { button1.Text = "Starting"; button1.Enabled = false; button1Worker.RunWorkerAsync(); } private
private void button1Click(object sender, EventArgs e)
{
button1.Text = "Starting";
button1.Enabled = false;
button1Worker.RunWorkerAsync();
}
private void button1worker_DoWork(object sender, DoWorkEventArgs e)
{
toolStarter.startTool("button1");
}
private void button1worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.Text = "Autoruns";
button1.Enabled = true;
}
此解决方案按照预期/预期工作,但是相同的代码在15个不同的按钮上重复,这对我来说似乎是错误的
你能推荐其他方法做同样的事情吗
我确实尝试了
ThreadPool
队列,但在任务完成后没有更新UI。您可以改为通过async/await执行此操作,这简化了代码并消除了对后台工作人员的需要:
如果您的按钮都在执行相同的操作,但仅更改字符串,则可以重构该按钮以支持该操作:
private async Task ExecuteButton(Button button, string toolName)
{
button.Text = "Starting";
button.Enabled = false;
await Task.Run(() => toolStarter.startTool(toolName));
button.Text = "Autoruns";
button.Enabled = true;
}
private async void button1Click(object sender, EventArgs e)
{
await ExecuteButton(button1, "button1");
// Do any other specific stuff for after here
}
// Use for other buttons as needed
private async void button2Click(object sender, EventArgs e)
{
await ExecuteButton(button2, "button2");
}
谢谢,这真是太棒了!
private async Task ExecuteButton(Button button, string toolName)
{
button.Text = "Starting";
button.Enabled = false;
await Task.Run(() => toolStarter.startTool(toolName));
button.Text = "Autoruns";
button.Enabled = true;
}
private async void button1Click(object sender, EventArgs e)
{
await ExecuteButton(button1, "button1");
// Do any other specific stuff for after here
}
// Use for other buttons as needed
private async void button2Click(object sender, EventArgs e)
{
await ExecuteButton(button2, "button2");
}
// This is your helper class that actually does the work
public class ToolStarter
{
public void startTool(string name)
{
// Put your switch statement here to decide what work to do
}
}
public class ButtonWorker
{
private Button button;
private ToolStarter toolStarter;
public ButtonWorker(Button button, ToolStarter toolStarter)
{
this.button = button;
this.toolStarter = toolStarter;
this.button.Enabled = false;
this.button.Text = "Starting";
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork));
}
private void DoWork(object state)
{
this.toolStarter.startTool(button.Name);
// Pass control back to the UI thread so you can update your
// button text and enabled/status
this.button.Invoke(new Action(() =>
{
this.button.Text = "Autoruns";
this.button.Enabled = true;
}));
}
}
// This is just showing you how to use the ButtonWorker
public class ButtonWorkerTest
{
public ButtonWorkerTest()
{
var btn1 = new Button { Name = "button1" };
var btn2 = new Button { Name = "button2" };
var toolstarter = new ToolStarter(); // This is your class
var worker1 = new ButtonWorker(btn1, toolstarter);
var worker2 = new ButtonWorker(btn2, toolstarter);
}
}