C# 后台加载字典
这看起来应该很简单,但显然不是 我有一个字典,需要在程序启动时加载40000个条目。 它只延迟加载时间约5-7秒,但我希望在后台这样做以避免这种情况 在下面的代码中,有3个部分涉及dictionary和BackgroundWorkerI目前拥有的功能 我知道这段代码使用了PopulateSicCodeDictionary方法,但由于某些原因,它实际上没有启动该方法 我做错了什么C# 后台加载字典,c#,wpf,multithreading,dictionary,backgroundworker,C#,Wpf,Multithreading,Dictionary,Backgroundworker,这看起来应该很简单,但显然不是 我有一个字典,需要在程序启动时加载40000个条目。 它只延迟加载时间约5-7秒,但我希望在后台这样做以避免这种情况 在下面的代码中,有3个部分涉及dictionary和BackgroundWorkerI目前拥有的功能 我知道这段代码使用了PopulateSicCodeDictionary方法,但由于某些原因,它实际上没有启动该方法 我做错了什么 static BackgroundWorker populateZipCodeDictionary;
static BackgroundWorker populateZipCodeDictionary;
public MainWindow()
{
populateZipCodeDictionary = new BackgroundWorker();
populateZipCodeDictionary.DoWork += populateZipCodeDictionary_DoWork;
populateZipCodeDictionary.RunWorkerCompleted += populateZipCodeDictionary_RunWorkerCompleted;
populateZipCodeDictionary.RunWorkerAsync();
}
static void populateZipCodeDictionary_DoWork(object sender, DoWorkEventArgs e)
{
ZipCodes.PopulateZipCodeDictionary();
}
static void populateZipCodeDictionary_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Dictionary loaded");
}
这是一个用于后台处理的例程。您只需在处理完成时给runback一个要执行的操作和一个要调用的操作
public class Worker
{
private Dispatcher _appDispatcher = Dispatcher.CurrentDispatcher;
private Dispatcher _workerDispatcher;
private Thread _workerThread;
public Worker()
{
_workerThread = new Thread(RunWorkerThread);
_workerThread.Start();
}
public void RunBehind(Action a_action, Action a_callback)
{
_workerDispatcher.BeginInvoke(new Action(() =>
{
a_action();
_appDispatcher.BeginInvoke(a_callback);
}));
}
private void RunWorkerThread()
{
Thread.CurrentThread.Name = "AppWorker";
_workerDispatcher = Dispatcher.CurrentDispatcher;
Dispatcher.Run();
}
}
也可以尝试锁定
static class ZipCodes
{
private static Object zipLocker = new Object();
#region Methods
public static string GetValue(string key)
{
lock (zipLocker)
{
string result;
if (zipCodeDictionary.TryGetValue(key, out result))
{
return result;
}
else
{
return null;
}
}
}
#endregion
#region ZipCode Dictionary Definition
static Dictionary<string, string> zipCodeDictionary = null;
public static void PopulateZipCodeDictionary()
{
Dictionary<string, string> workingDictionary = new Dictionary<string, string>();
workingDictionary.Add( "00501", "Holtsville, NY" );
workingDictionary.Add( "00544", "Holtsville, NY" );
workingDictionary.Add( "00601", "Adjuntas, PR" );
workingDictionary.Add( "00602", "Aguada, PR" );
workingDictionary.Add( "00603", "Aguadilla, PR" );
workingDictionary.Add( "00604", "Aguadilla, PR" );
//Continues on adding ~40k entries...
lock (zipLocker)
{
zipCodeDictionary = workingDictionary;
}
}
}
这是一个用于后台处理的例程。您只需在处理完成时给runback一个要执行的操作和一个要调用的操作
public class Worker
{
private Dispatcher _appDispatcher = Dispatcher.CurrentDispatcher;
private Dispatcher _workerDispatcher;
private Thread _workerThread;
public Worker()
{
_workerThread = new Thread(RunWorkerThread);
_workerThread.Start();
}
public void RunBehind(Action a_action, Action a_callback)
{
_workerDispatcher.BeginInvoke(new Action(() =>
{
a_action();
_appDispatcher.BeginInvoke(a_callback);
}));
}
private void RunWorkerThread()
{
Thread.CurrentThread.Name = "AppWorker";
_workerDispatcher = Dispatcher.CurrentDispatcher;
Dispatcher.Run();
}
}
也可以尝试锁定
static class ZipCodes
{
private static Object zipLocker = new Object();
#region Methods
public static string GetValue(string key)
{
lock (zipLocker)
{
string result;
if (zipCodeDictionary.TryGetValue(key, out result))
{
return result;
}
else
{
return null;
}
}
}
#endregion
#region ZipCode Dictionary Definition
static Dictionary<string, string> zipCodeDictionary = null;
public static void PopulateZipCodeDictionary()
{
Dictionary<string, string> workingDictionary = new Dictionary<string, string>();
workingDictionary.Add( "00501", "Holtsville, NY" );
workingDictionary.Add( "00544", "Holtsville, NY" );
workingDictionary.Add( "00601", "Adjuntas, PR" );
workingDictionary.Add( "00602", "Aguada, PR" );
workingDictionary.Add( "00603", "Aguadilla, PR" );
workingDictionary.Add( "00604", "Aguadilla, PR" );
//Continues on adding ~40k entries...
lock (zipLocker)
{
zipCodeDictionary = workingDictionary;
}
}
}
我只看到两种情况:
DoWork事件处理程序实际上已经执行了,但不知何故您忽略了这一点,设置断点将是查看实际情况的最有效方法
出现了一些问题,因此RunWorkerCompleted事件在事件参数中出现错误
MSDN
在后台操作已完成或已取消时发生,
或者提出了一个例外。
系统的误差特性
System.ComponentModel.RunWorkerCompletedEventArgs表示
该操作引发了异常
我只看到两种情况:
DoWork事件处理程序实际上已经执行了,但不知何故您忽略了这一点,设置断点将是查看实际情况的最有效方法
出现了一些问题,因此RunWorkerCompleted事件在事件参数中出现错误
MSDN
在后台操作已完成或已取消时发生,
或者提出了一个例外。
系统的误差特性
System.ComponentModel.RunWorkerCompletedEventArgs表示
该操作引发了异常
尝试将已完成的事件处理程序更改为:
static void populateZipCodeDictionary_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
MessageBox.Show(e.Error.ToString());
else
MessageBox.Show("Dictionary loaded");
}
我猜您的DoWork处理程序正在引发异常。尝试将已完成的事件处理程序更改为:
static void populateZipCodeDictionary_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
MessageBox.Show(e.Error.ToString());
else
MessageBox.Show("Dictionary loaded");
}
我猜您的DoWork处理程序正在抛出一个异常。这看起来是正确的,如果在PopulateSicCodeDictionary方法中放入Debug.WriteLine,它会被调用吗?该方法是否引发了任何期望?您可能还希望将ZipCode移动到数据库或文本文件中并读取,而不是将它们全部硬编码,因为这样更容易保持最新,并将代码减少40k行。您在ZipCode类中执行了哪种类型的调试,是否省略了任何代码,您是否已完成此操作?我在zipCodeDictionary的第一个位置放置了一个断点。添加语句,但它从未触发。在ZipCodes.PopulateZipCodeDictionary行上放置一个断点,然后进入代码,这是否有效?只是出于兴趣,您使用的Visual Studio和.Net版本是什么?您是在调试器中运行它还是有测试工具?这看起来是正确的,如果您将Debug.WriteLine放在populateSicCodeDictionary方法中,它会被调用吗?该方法是否引发了任何期望?您可能还希望将ZipCode移动到数据库或文本文件中并读取,而不是将它们全部硬编码,因为这样更容易保持最新,并将代码减少40k行。您在ZipCode类中执行了哪种类型的调试,是否省略了任何代码,您是否已完成此操作?我在zipCodeDictionary的第一个位置放置了一个断点。添加语句,但它从未触发。在ZipCodes.PopulateZipCodeDictionary行上放置一个断点,然后进入代码,这是否有效?只是出于兴趣,您使用的Visual Studio和.Net版本是什么?您是在调试器中运行它,还是有测试线束?1。是的,它被执行了,只是它里面的方法没有执行。2.VS调试器没有抛出任何错误。问题是,当这一切完成时,字典是不可搜索/空的。MessageBox命令纯粹是为了查看工作线程是否/何时完成。请在Visual Studio菜单“调试”->“异常”中启用CLR异常,然后再次启动应用程序,现在是否有异常?1。是的,它被执行了,只是它里面的方法没有执行。2.VS调试器没有抛出任何错误。问题是,当这一切完成时,字典是不可搜索/空的。MessageBox命令纯粹是为了查看工作线程是否/何时完成。请在Visual Studio菜单“调试->异常”中启用CLR异常,然后再次启动应用程序,现在有异常吗?我如何才能看到该异常?我假设BS会在异常发生时指出异常,对吗?如果你是说VS Visual Studio,并且你在调试器下运行应用程序,那么当异常发生时,它应该会中断。是的,这就是VS…可怕的打字错误,嗯;。没有e
异常正在抛出,我如何才能看到该异常?我假设BS会在异常发生时指出异常,对吗?如果你是说VS Visual Studio,并且你在调试器下运行应用程序,那么当异常发生时,它应该会中断。是的,这就是VS…可怕的打字错误,嗯;。没有抛出异常。谢谢你,这是你创建的一个很棒的方法。这无疑简化了c的这一方面。谢谢,我很高兴。我喜欢C。我只是希望调度员能在Silverlight中使用。也许在Silverlight 5中。谢谢你,这是你创造的一个很棒的方法。这无疑简化了c的这一方面。谢谢,我很高兴。我喜欢C。我只是希望调度员能在Silverlight中使用。也许在Silverlight 5。