我有一个简单的应用程序,可以触发一系列数据密集型任务。我对 WinForms 不是很有经验,我想知道在不锁定界面的情况下最好的方法。backgroundWorker 可以重复使用,还是有其他方法可以做到这一点?
谢谢
我有一个简单的应用程序,可以触发一系列数据密集型任务。我对 WinForms 不是很有经验,我想知道在不锁定界面的情况下最好的方法。backgroundWorker 可以重复使用,还是有其他方法可以做到这一点?
谢谢
BackgroundWorker
是一个还包括通知同步的线程。例如,如果您想在扫描完成时更新您的 UI,则常规Thread
无法访问 UI 对象(只有 UI 线程可以这样做);因此,BackgroundWorker
提供了一个 Completed 事件处理程序,该处理程序在操作完成时在 UI 线程上运行。
有关更多信息,请参阅:演练:使用 BackgroundWorker 组件进行多线程 (MSDN)
和一个简单的示例代码:
var worker = new System.ComponentModel.BackgroundWorker();
worker.DoWork += (sender,e) => Thread.Sleep(60000);
worker.RunWorkerCompleted += (sender,e) => MessageBox.Show("Hello there!");
worker.RunWorkerAsync();
backgroundWorker
可以使用。
它的好处 - 它允许您更新进度条并与 UI 控件交互。( WorkerReportsProgress
)
它还具有取消机制。( WorkerSupportsCancellation
)
您可以使用 BackgroundWorker 来满足此类要求。下面是一个示例updates a label status based on percentage task [long running] completion
。ProgressChanged
此外,还有一个示例业务类,它设置了一些值,并通过处理程序将值设置回 UI 。DoWork
是您编写长时间运行的任务逻辑的地方。在 Winforms 应用程序上添加标签和 backgroundworker 组件后复制粘贴下面的代码并试一试。您可以调试各种处理程序[RunWorkerCompleted, ProgressChanged, DoWork]
并查看InitWorker
方法。也请注意cancellation feature
。
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
private BackgroundWorker _worker;
BusinessClass _biz = new BusinessClass();
public Form3()
{
InitializeComponent();
InitWorker();
}
private void InitWorker()
{
if (_worker != null)
{
_worker.Dispose();
}
_worker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_worker.DoWork += DoWork;
_worker.RunWorkerCompleted += RunWorkerCompleted;
_worker.ProgressChanged += ProgressChanged;
_worker.RunWorkerAsync();
}
void DoWork(object sender, DoWorkEventArgs e)
{
int highestPercentageReached = 0;
if (_worker.CancellationPending)
{
e.Cancel = true;
}
else
{
double i = 0.0d;
int junk = 0;
for (i = 0; i <= 199990000; i++)
{
int result = _biz.MyFunction(junk);
junk++;
// Report progress as a percentage of the total task.
var percentComplete = (int)(i / 199990000 * 100);
if (percentComplete > highestPercentageReached)
{
highestPercentageReached = percentComplete;
// note I can pass the business class result also and display the same in the LABEL
_worker.ReportProgress(percentComplete, result);
_worker.CancelAsync();
}
}
}
}
void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
// Display some message to the user that task has been
// cancelled
}
else if (e.Error != null)
{
// Do something with the error
}
}
void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = string.Format("Result {0}: Percent {1}",e.UserState, e.ProgressPercentage);
}
}
public class BusinessClass
{
public int MyFunction(int input)
{
return input+10;
}
}
}
后台工作人员将是一个不错的选择
有关更多信息,请查看此处 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx