C# 自己的SynchronizedCollection的Json.net序列化

C# 自己的SynchronizedCollection的Json.net序列化,c#,json.net,C#,Json.net,我已经编写了一个非常基本的同步集合,用于桌面应用程序。有没有比这更好/更容易的方法?集合需要由json.net直接序列化,显然它需要同步 我还想知道是否可以强制转换为未知的泛型类型来调用copy函数generic,而无需强制转换到接口。我认为这在一个大的列表中可能非常缓慢,而且似乎没有必要 public class SynchronizedCollectionConverter : JsonConverter { public override bool CanConvert(Type

我已经编写了一个非常基本的同步集合,用于桌面应用程序。有没有比这更好/更容易的方法?集合需要由json.net直接序列化,显然它需要同步

我还想知道是否可以强制转换为未知的泛型类型来调用copy函数generic,而无需强制转换到接口。我认为这在一个大的列表中可能非常缓慢,而且似乎没有必要

public class SynchronizedCollectionConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
         return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(SynchronizedCollection<>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        // make list type from SynchronizedCollection generic type
        var listType = typeof(List<>).MakeGenericType(objectType.GenericTypeArguments[0]);
        // create instance of list type
        var list = Activator.CreateInstance(listType);

        // populate json to our list!
        serializer.Populate(reader, list);

        // create new SynchronizedCollection from populated list, easy! <3 json <3 c#
        return Activator.CreateInstance(objectType, list);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        SynchronizedCollectionCopy collection = value as SynchronizedCollectionCopy;

        // get a copy of the list synchronously
        using (var waitTask = Task.Run<List<object>>(async () => { return await collection.Copy(); }))
        {
            // wait for synchronization.
            waitTask.Wait();

            // aaand serialize
            serializer.Serialize(writer, waitTask.Result);
        }            
    }
}

public interface SynchronizedCollectionCopy
{
    Task<List<object>> Copy();
}

public class SynchronizedCollection<T> : IDisposable, SynchronizedCollectionCopy
{
    private List<T> _storage;
    private SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

    public int Count { get { return _storage.Count; } }

    public SynchronizedCollection()
    {
        _storage = new List<T>();
    }
    public SynchronizedCollection(IEnumerable<T> items)
    {
        _storage = new List<T>(items);
    }

    public async Task Add(T item)
    {
        await _lock.WaitAsync();
        try
        {
            _storage.Add(item);
        }
        catch
        {
            throw;
        }
        finally
        {
            _lock.Release();
        }
    }
    public async Task Remove(Func<T, bool> predicate)
    {
        await _lock.WaitAsync();

        try
        {
            T item;
            while ((item = _storage.FirstOrDefault(predicate)) != null)
            {
                _storage.Remove(item);
            }
        }
        catch
        {
            throw;
        }
        finally
        {
            _lock.Release();
        }
    }
    public async Task Perform(Action<List<T>> actionOnList)
    {
        await _lock.WaitAsync();
        try
        {
            actionOnList(_storage);
        }
        catch
        {
            throw;
        }
        finally
        {
            _lock.Release();
        }
    }
    public async Task<List<object>> Copy()
    {
        await _lock.WaitAsync();
        List<object> list = null;

        try
        {
            list = new List<object>(_storage.Cast<object>());
        }
        catch
        {
            throw;
        }
        finally
        {
            _lock.Release();
        }

        return list;
    }

    public void Dispose()
    {
        _lock.Dispose();
    }
}
公共类SynchronizedCollectionConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
返回objectType.IsGenericType&&objectType.GetGenericTypeDefinition()==typeof(SynchronizedCollection);
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
if(reader.TokenType==JsonToken.Null)
返回null;
//从SynchronizedCollection泛型类型生成列表类型
var listType=typeof(List).MakeGenericType(objectType.GenericTypeArguments[0]);
//创建列表类型的实例
var list=Activator.CreateInstance(listType);
//将json填充到我们的列表中!
序列化程序。填充(读取器、列表);

//从填充的列表中创建新的SynchronizedCollection,很简单!1)鉴于您的类没有实现
ICollection
,这可能是最简单的。2)转换到接口应该花费很少的时间,比Json.NET完成的任何工作都要少。但是多次调用
Activator.CreateInstance
可能需要一些时间。您是否已经对它进行了剖析?参见3)通过返回<代码>列表>代码>框值类型。考虑返回<代码> t[] /Cords>类型为<代码>系统。数组< /代码>并允许Json.NET推断元素类型。还考虑提供一个非异步版本的<代码>()/代码>以方便。4)在您的代码> Read jSar()中。
忽略传入的
对象值
。您可能需要检查它是否非空,是否可以强制转换为
同步集合
,如果是,则填充并返回它,而不是填充并返回新值。5)而不是分两步分配并填充
列表
,只需在一步中使用。6)S由于您的代码有效,这个问题可能更适合Thx的建议!我完全忘记了SE上的codereview。对于第4点,在调用ReadJson时,在什么情况下可以设置对象值?我没有正确地表达我自己,转换到接口的速度很快,我知道,但将整个列表转换到列表,我甚至不需要知道WriteJson可能会很慢。在什么情况下调用ReadJson时可以设置对象值?-例如,当使用get only预分配集合反序列化到对象时,例如
public class RootObject{readonly observeCollection collection=new observeableCollection();公共observeCollection集合{get{return Collection;}}}}