【问题标题】:Protrobuf - Error : Timeout while inspecting metadataProtrobuf - 错误:检查元数据时超时
【发布时间】:2013-05-10 14:11:38
【问题描述】:

我收到以下异常

"检查元数据时超时;这可能表示死锁。这通常可以通过在应用程序初始化期间准备必要的序列化程序来避免,而不是允许多个线程执行初始元数据检查;另请参阅 LockContended 事件 ( System.String)"

尝试使用 protobuf.net 序列化/反序列化对象时。 我将 protobuf.net 用于 Silverlight 和 WCF 服务。在 WCF 服务上序列化结果并在客户端(Silverlight)端反序列化相同的响应。

我为此使用了扩展方法。这是代码

 public static byte[] GetSerializeByteArray<T>( this T entity )
    {
          using ( var stream = new MemoryStream() )
            {
                Serializer.Serialize( stream, entity );
                return stream.ToArray();
            }
    }

  public static T DeserializeByteArray<T>( this byte[] byteArray )
    {
        if ( byteArray == null )
        {
            throw new ArgumentNullException( "byteArray" );
        }
        try
        {
            using ( Stream result = new MemoryStream( byteArray ) )
            {
                return Serializer.Deserialize<T>( result );
            }
        }
        catch ( Exception )
        {
            throw new InvalidOperationException( "Invalid Type" );
        }
    }

这是我们的模型类,它驻留在其他项目(可移植类库)中,并在客户端(Silverlight)和服务器(WCF)端都使用。

 [ProtoContract]
public class Class1
{
    [ProtoMember( 1 )]
    public string Name       
 }

我不明白为什么这个异常一次又一次地发生! 你能解释一下吗,这是使用protobuf-net实现的正确方法吗?

【问题讨论】:

  • 这很奇怪!该模型是微不足道的 - 它应该立即解决。您能告诉我确切您使用的是哪个 dll 版本号吗?以及什么平台版本(完整的.net/可移植类库/等)。另外 - 这会发生在客户端和服务器上吗?还是只有一个?你不应该在这里做任何特别的事情。奇怪的事情正在发生!不太可能,但这里的超时实际上是可配置的 - 你有没有可能改变它?

标签: .net wcf silverlight-5.0 protobuf-net


【解决方案1】:

我已经使用您问题中的代码创建了一个测试装置,带有一个简单的按钮等 - 以下工作正常:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var obj = new Class1 { Name = "abc" };
        var raw = obj.GetSerializeByteArray();
        var clone = raw.DeserializeByteArray<Class1>();
        ((Button)sender).Content = clone.Name;
    }

即按钮的文本设置为"abc",我们序列化和反序列化的值。对于这个测试,我使用的是 NuGet 下载(即项目中的“管理 NuGet 包...”),它选择了 2.0.0.621,自动选择 Silverlight 构建。

没有遇到任何问题。可能性:

  • 您是否使用了不同的 dll?也许是可移植类库 (PCL) 版本?这不会是错误的,因为 PCL 版本应该在 Silverlight 上运行 - 我只是想找到一个解释,为什么我不能重现你所看到的。例如,理论上可能存在我需要调查的 PCL 版本 only 中的错误。
  • 您的实际模型要复杂得多吗?您可能会查看RuntimeTypeModel.Default.MetadataTimeoutMilliseconds - 这应该默认为 5 秒,这在任何正常情况下都是很长的时间 - 知道增加它是否会使其工作 会很有趣,或者是否可能一些代码已经将其更改为更小的值

我不知道是不是,但是如果问题是你有一个非常复杂的模型(也许也在加载大量外部程序集),那么另一种选择可能是预生成序列化程序集。这意味着您可以将所有反射分析、思考、IL 发射等提前移动到构建时(而不是运行时),生成您可以引用的 dll。这是described here,基本上您只需生成序列化 dll,从您的 silverligh 项目中引用它,然后将该代码替换为:

public static byte[] GetSerializeByteArray<T>(this T entity)
{
    using (var stream = new MemoryStream())
    {
        new MyCustomSerializer().Serialize(stream, entity);
        return stream.ToArray();
    }
}

public static T DeserializeByteArray<T>(this byte[] byteArray)
{
    if (byteArray == null)
    {
        throw new ArgumentNullException("byteArray");
    }
    try
    {
        using (Stream result = new MemoryStream(byteArray))
        {
            return (T)(new MyCustomSerializer().Deserialize(result, null, typeof(T)));
        }
    }
    catch (Exception)
    {
        throw new InvalidOperationException("Invalid Type");
    }
}

其中MyCustomSerializer 是您所称的生成类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多