Json.net自己的SynchronizedCollection序列化

时间:2017-05-07 12:08:07

标签: c# json.net

我已经编写了一个非常基本的同步集合,可以在桌面应用中使用。有没有办法比这更好/更容易?该集合需要由json.net直接序列化,显然需要进行同步。

此外,我想知道是否可以转换为未知的泛型类型来调用复制函数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();
    }
}

0 个答案:

没有答案