C# 后台加载字典

C# 后台加载字典,c#,wpf,multithreading,dictionary,backgroundworker,C#,Wpf,Multithreading,Dictionary,Backgroundworker,这看起来应该很简单,但显然不是 我有一个字典,需要在程序启动时加载40000个条目。 它只延迟加载时间约5-7秒,但我希望在后台这样做以避免这种情况 在下面的代码中,有3个部分涉及dictionary和BackgroundWorkerI目前拥有的功能 我知道这段代码使用了PopulateSicCodeDictionary方法,但由于某些原因,它实际上没有启动该方法 我做错了什么 static BackgroundWorker populateZipCodeDictionary;

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

我有一个字典,需要在程序启动时加载40000个条目。 它只延迟加载时间约5-7秒,但我希望在后台这样做以避免这种情况

在下面的代码中,有3个部分涉及dictionary和BackgroundWorkerI目前拥有的功能

我知道这段代码使用了PopulateSicCodeDictionary方法,但由于某些原因,它实际上没有启动该方法

我做错了什么

    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。