C# WPF字典绑定失败非常缓慢

C# WPF字典绑定失败非常缓慢,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我的应用程序绑定了大部分标签对象,这样就可以从Web服务中替换它们 我把我的替代品储存在字典里。根据为应用程序加载的客户端的不同,替换内容也会有所不同 我遇到的问题是,大多数时候我不会替换标签,绑定失败会抛出一个非常缓慢的异常 下面是一个示例:(请注意,此代码功能正确,如果找不到匹配项,则速度很慢。) 因为我有很多这样的东西,所以我花了整整一秒钟的时间来浏览它们 有没有办法使绑定在字典查找失败时不引发异常?或者以某种方式更快地失败?是的,如果不在调试器中运行代码,速度可以显著提高。实际上,在Vi

我的应用程序绑定了大部分
标签
对象,这样就可以从Web服务中替换它们

我把我的替代品储存在字典里。根据为应用程序加载的客户端的不同,替换内容也会有所不同

我遇到的问题是,大多数时候我不会替换标签,绑定失败会抛出一个非常缓慢的异常

下面是一个示例:(请注意,此代码功能正确,如果找不到匹配项,则速度很慢。)

因为我有很多这样的东西,所以我花了整整一秒钟的时间来浏览它们


有没有办法使绑定在字典查找失败时不引发异常?或者以某种方式更快地失败?

是的,如果不在调试器中运行代码,速度可以显著提高。实际上,在VisualStudio中打印stackteace是迄今为止最慢的部分。如果您在运行应用程序时没有附加调试器,我敢肯定性能损失将不再明显

我遇到了一个类似的问题,我们在库中捕获一个异常,即使您这样做,VS也会在每次捕获(并处理)异常时打印一条关于在代码中捕获第一次异常的注释。该异常在启动时被触发了大约50次,应用程序启动大约需要10秒,这一切都是因为控制台日志记录。一旦我在没有调试器的情况下运行应用程序,它几乎立即启动

因此,尝试解决该异常可能只是过早的优化。

编辑:

实际上,所有这一切只是在VS输出窗格中禁用输出。它实际上并没有加快速度

原件:

我也有类似的问题,但我想捕捉并记录错误。但是,您可以使用以下解决方案简单地禁用将错误输出到VS2010输出窗口。解决方案分为两部分,第一部分是简单类:

using System.Diagnostics;

namespace DevBindingErrors
{
    /// <summary>
    /// Intercepts all binding error messages. Stops output appearing in VS2010 debug window.
    /// </summary>
    class BindingTraceListener: TraceListener
    {
        private string _messageType;

        public override void Write(string message)
        {
            // Always happens in 2 stages: first stage writes "System.Windows.Data Error: 40 :" or similar.
            _messageType = message;
        }

        public override void WriteLine(string message)
        {
            Debug.WriteLine(string.Format("{0}{1}", _messageType, message));
        }
    }
}
使用系统诊断;
命名空间devBindinger错误
{
/// 
///截获所有绑定错误消息。停止VS2010调试窗口中显示的输出。
/// 
类BindingTraceListener:TraceListener
{
私有字符串_messageType;
公共重写无效写入(字符串消息)
{
//始终分两个阶段进行:第一阶段写入“System.Windows.Data错误:40:”或类似内容。
_messageType=消息;
}
公共覆盖无效写线(字符串消息)
{
Debug.WriteLine(string.Format(“{0}{1}”,_messageType,message));
}
}
}
第二部分在App.xaml.cs中:

using System.Diagnostics;
using System.Windows;

namespace DevBindingErrors
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            PresentationTraceSources.Refresh();
            PresentationTraceSources.DataBindingSource.Listeners.Add(new BindingTraceListener());
            PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Warning;
        }
    }
}
使用系统诊断;
使用System.Windows;
命名空间devBindinger错误
{
/// 
///App.xaml的交互逻辑
/// 
公共部分类应用程序:应用程序
{
公共应用程序()
{
PresentationTraceSources.Refresh();
PresentationOnTraceSources.DataBindingSource.Listeners.Add(新BindingTraceListener());
PresentationOnTraceSources.DataBindingSource.Switch.Level=SourceLevel.Warning;
}
}
}
如果要忽略所有绑定错误,只需注释掉
Debug.WriteLine(…)
行。(不过我并不推荐这样做)这也会加快执行速度,同时不会失去调试应用程序的能力


这个解决方案的想法来自于WPF,它也有关于WPF中跟踪源的更多细节。

如果您有选择,我会将您的
IDictionary
实现更改为返回
null
的实现,并改为使用
TargetNullValue
(如果您仍然使用
FallbackValue
,甚至可以是
IDictionary
并返回
dependencProperty.UnsetValue
):

公共类PassthruDictionary:IDictionary
{
私有字典实例;
//…其他东西
公共TValue此[TKey]
{
得到
{
t价值;
if(instance.TryGetValue(key,out值))
{
返回值;
}
其他的
{
返回默认值(TValue);
}
}
//……更多
}
}

您无法定义跟踪。不确定这对于澄清问题来说是否太旧,但问题是:我似乎找不到返回DependecyProeprty.unset值的方法。假设我有一个
PassthruDictionary
,我如何返回unset值?(它会编译,但会为我抛出一个运行时异常。)
using System.Diagnostics;
using System.Windows;

namespace DevBindingErrors
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            PresentationTraceSources.Refresh();
            PresentationTraceSources.DataBindingSource.Listeners.Add(new BindingTraceListener());
            PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Warning;
        }
    }
}
public class PassthruDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    private Dictionary<TKey, TValue> instance;

    // ... other stuff

    public TValue this[TKey key]
    {
        get
        {
            TValue value;
            if (instance.TryGetValue(key, out value))
            {
                return value;
            }
            else
            {
                return default(TValue);
            }
        }
        // ... more
    }
}