这看起来应该很简单,但显然不是。
我有一本字典需要在程序启动时加载~40,000个条目。 它只会将加载时间延迟大约5-7秒,但我想在后台进行以避免这种情况。
在下面的代码中,有3个部分处理我目前拥有的dictionary
和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");
}
static class ZipCodes
{
#region Methods
public static string GetValue(string key)
{
string result;
if (zipCodeDictionary.TryGetValue(key, out result))
{
return result;
}
else
{
return null;
}
}
#endregion
#region ZipCode Dictionary Definition
static Dictionary<string, string> zipCodeDictionary = new Dictionary<string, string>();
public static void PopulateZipCodeDictionary()
{
zipCodeDictionary.Add( "00501", "Holtsville, NY" );
zipCodeDictionary.Add( "00544", "Holtsville, NY" );
zipCodeDictionary.Add( "00601", "Adjuntas, PR" );
zipCodeDictionary.Add( "00602", "Aguada, PR" );
zipCodeDictionary.Add( "00603", "Aguadilla, PR" );
zipCodeDictionary.Add( "00604", "Aguadilla, PR" );
//Continues on adding ~40k entries...
}
答案 0 :(得分:2)
这是我用于后台处理的例程。您只需提供RunBehind
要执行的操作,并在处理完成时调用操作。
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;
}
}
}
答案 1 :(得分:1)
我只看到两个案例:
DoWork
事件处理程序实际上已经执行了,你错过了这一点,提出一个断点将是查看实际情况的最有效方式RunWorkerCompleted
事件引发了事件args中的错误MSDN,BackgroundWorker.RunWorkerCompleted Event
在后台操作完成后发生,已取消, 或者提出了例外。 的错误属性 System.ComponentModel.RunWorkerCompletedEventArgs表示一个 操作抛出了异常
答案 2 :(得分:1)
尝试将已完成的事件处理程序更改为:
static void populateZipCodeDictionary_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
MessageBox.Show(e.Error.ToString());
else
MessageBox.Show("Dictionary loaded");
}
我的猜测是你的DoWork处理程序抛出异常。