Загрузка словаря в фоновом режиме - PullRequest
2 голосов
/ 23 марта 2012

Кажется, это должно быть так просто, но, очевидно, это не так.

У меня есть словарь, который должен загрузить ~ 40000 записей при запуске программы. Это только задерживает время загрузки примерно на 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...
    }

Ответы [ 3 ]

2 голосов
/ 23 марта 2012

Это процедура, которую я использую для фоновой обработки.Вы просто даете 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 голос
/ 23 марта 2012

Попробуйте изменить обработчик завершенного события следующим образом:

static void populateZipCodeDictionary_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
        MessageBox.Show(e.Error.ToString());
    else
        MessageBox.Show("Dictionary loaded");
}

Я предполагаю, что ваш обработчик DoWork вызывает исключение.

1 голос
/ 23 марта 2012

Я вижу только два случая:

  1. DoWork обработчик событий был фактически выполнен, и вы почему-то упустили это, установив точку останова, было бы наиболее эффективным способом увидеть, что на самом деле происходит
  2. Возникла некоторая проблема, поэтому событие RunWorkerCompleted возникло с ошибкой в ​​аргументах события

MSDN, BackgroundWorker.RunWorkerCompleted Event

Происходит, когда фоновая операция завершена, отменена или вызвала исключение.Свойство Error объекта System.ComponentModel.RunWorkerCompletedEventArgs указывает, что исключение было вызвано операцией

...