字典加载在背景中

时间:2012-03-23 17:02:13

标签: c# wpf multithreading dictionary backgroundworker

这看起来应该很简单,但显然不是。

我有一本字典需要在程序启动时加载~40,000个条目。 它只会将加载时间延迟大约5-7秒,但我想在后台进行以避免这种情况。

在下面的代码中,有3个部分处理我目前拥有的dictionaryBackgroundWorker

我知道这段代码适用于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...
    }

3 个答案:

答案 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)

我只看到两个案例:

  1. DoWork事件处理程序实际上已经执行了,你错过了这一点,提出一个断点将是查看实际情况的最有效方式
  2. 引发了一些问题,因此RunWorkerCompleted事件引发了事件args中的错误
  3. 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处理程序抛出异常。