我一直在玩.net 2.0中以线程安全的方式安全地调用方法的方法。
我的树视图是通过在单独的线程上调用数据库来填充的;
下面是我尝试使用我的InvokeFunction方法(如下所示)......它有效,但我希望有更好的方法来写这个...对此有什么想法?
InvokeFunction(delegate() { TreeView1.Nodes.Clear(); });
delegate void FunctionDelegate();
private delegate void ThreadSafeProcess(FunctionDelegate func);
private void InvokeFunction(FunctionDelegate func)
{
if (this.InvokeRequired)
{
ThreadSafeProcess d = new ThreadSafeProcess(InvokeFunction);
this.Invoke(d, new object[] { func });
}
else
{
func();
}
}
答案 0 :(得分:3)
BackgroundWorker
是.NET 2.0中更清晰的解决方案。
它将为您创建一个线程并负责同步。
您可以在设计模式下将BackgroundWorker
组件添加到Form。
您订阅了DoWork
活动。当您在UI线程中调用backgroundWorker.RunWorkerAsync()
时,订阅此方法的方法将在后台线程中执行。
当您需要从后台线程与UI线程进行交互时,请调用backgroundWorker.ReportProgress
。
这将触发ProgressChanged
事件。 ProgressChanged
事件始终在UI线程中执行。
您可以使用userState
backgroundWorker.ReportProgress
参数将任何数据传递给UI线程。例如,在您的情况下,添加新的TreeView
节点所需的数据。
您实际上会在ProgressChanged
事件处理程序中添加新节点。
以下是MSDN的链接:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx。
请注意,您不必使用方法percentProgress
方法的ReportProgress
参数。虽然您有一个进度条来反映后台工作进度很方便。
答案 1 :(得分:0)
除非你分享一些状态,否则你不必担心线程安全。函数总是在堆栈上接收它们的参数,堆栈对于每个线程都是本地的。所以功能不是你的问题。而是专注于国家。 “TreeView1”对象是一个值得担心的候选对象。