如何创建静态变量以避免产生数百个临时对象?

时间:2016-03-08 13:37:10

标签: c# multithreading

我有一个字符串序列化的自定义类

public string Serialize(BackgroundJobInfo info)
{
    ....
    var serializer = new DataContractSerializer(typeof(BackgroundJobInfo),
        null,
        int.MaxValue,
        true,
        true,
        new MongoDbSurrogate()); // MongoDbSurrogate : IDataContractSurrogate
    serializer.WriteObject(xmlWriter, info);
    ...
}

public BackgroundJobInfo Deserialize(string info)
{
      try
        {
            ...
            using (var textReader = new StringReader(info))
            {
                var serializer = new DataContractSerializer(typeof(BackgroundJobInfo));
                return (BackgroundJobInfo)serializer.ReadObject(xmlReader);
            }
        }
        catch (Exception e)
        {
        }
 }

serializer private static readonly避免产生数百个临时对象(它比我更快)是不是一个好主意?

如何做到这个线程安全? DataContractSerializer类的实例是线程安全的,除非实例与IDataContractSurrogateDataContractResolver的实现一起使用。

如何在线程安全的庄园中执行此操作,因为IDataContractoSurrogate不是线程安全的?

2 个答案:

答案 0 :(得分:0)

一个好的选择是将它标记为静态https://msdn.microsoft.com/en-us/library/system.threadstaticattribute(v=vs.110).aspx

这样每个线程就有一个实例,因此您不必担心跨线程访问:

[ThreadStatic]
public static DataContractSerializer serializer = new DataContractSerializer(typeof(BackgroundJobInfo),
    null,
    int.MaxValue,
    true,
    true,
    new MongoDbSurrogate());

那说创建单个实例然后垃圾收集的实际成本将是可以忽略的。因此,除非您的目标是超高性能,否则我建议您保留代码。

答案 1 :(得分:-1)

使用静态只读成员的替代方法是使用内置的MemoryCache对象来缓存DataContractSerializer,每次要处理时{2}都要求它MemoryCache序列化器。 MemoryCache商店是线程安全的,因此您不必担心它。

ObjectCache cache = MemoryCache.Default;
DataContractSerializer serializer = cache["MonogoSerialzier"] as DataContractSerializer;

if (serializer == null)
{
    serializer = new DataContractSerializer(typeof(BackgroundJobInfo),
        null,
        int.MaxValue,
        true,
        true,
        new MongoDbSurrogate()); // MongoDbSurrogate : IDataContractSurrogate

    // Cache the serializer with an policy that never expires the cache item.
    cache.Set("MonogoSerialzier", serializer, new CacheItemPolicy().AbsoluteExpiration);
}

serializer.WriteObject(xmlWriter, info);

这将在需要时从默认的内存缓存存储中获取它。如果它不存在,您可以实例化一个新的并将其填充到缓存存储中。您可以在缓存存储中存储多个实例,并根据需要使用不同的缓存策略。