2016-04-14 24 views
0

Şu anda akıştan verileri serileştirmek için benzer kodları kullanıyorum. Bu süreç büyük json dosya ve yavaş bağlantı için uzun sürebilir çünkü JSON.NET akışını kaldırma işlemini iptal etme

public static MyClass Parse(Stream stream) 
    { 
     var serializer = new JsonSerializer(); 
     using (var sr = new StreamReader(stream)) 
     using (var jsonTextReader = new JsonTextReader(sr)) 
     { 
      var result = serializer.Deserialize<MyClass>(jsonTextReader); 
      return result; 
     } 
    } 

o, kullanıcı tarafından başlatılan seriyi kaldırma iptali desteklemek mümkün mü?

+0

Ne yapmak istediğinizi anladığımdan emin değilim. Tek bir iş parçacığıyla çalışıyorsanız, kullanıcı nasıl iptal edebilir? Birden çok iş parçacığı ile çalıştırıyorsanız (.Net 3.5) neden bir ['BackgroundWorker '] (https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker (v = vs.90) kullanmayın. aspx)? Ayrıca bkz. Https://msdn.microsoft.com/en-us/library/ywkkz4s1%28v=vs.100%29.aspx – dbc

cevap

1

JsonTextReader kutunun dışında bu desteklemez, ancak okuyucu alt sınıf böylece Json.NET doğru (yani rethrow) istisnalar alt seviyesi kodu gelen ele alır ve

public class CancellableJsonTextReader : JsonTextReader 
{ 
    protected Func<bool> CheckCancelled { get; set; } 

    public CancellableJsonTextReader(TextReader reader, Func<bool> checkCancelled) 
     : base(reader) 
    { 
     this.CheckCancelled = checkCancelled; 
    } 

    public bool IsCancelled { get; private set; } 

    public override bool Read() 
    { 
     DoCheckCancelled(); 
     return base.Read(); 
    } 

    public override bool? ReadAsBoolean() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsBoolean(); 
    } 

    public override byte[] ReadAsBytes() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsBytes(); 
    } 

    public override DateTime? ReadAsDateTime() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsDateTime(); 
    } 

    public override DateTimeOffset? ReadAsDateTimeOffset() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsDateTimeOffset(); 
    } 

    public override decimal? ReadAsDecimal() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsDecimal(); 
    } 

    public override double? ReadAsDouble() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsDouble(); 
    } 

    public override int? ReadAsInt32() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsInt32(); 
    } 

    public override string ReadAsString() 
    { 
     DoCheckCancelled(); 
     return base.ReadAsString(); 
    } 

    private void DoCheckCancelled() 
    { 
     if (!IsCancelled && CheckCancelled != null) 
      IsCancelled = CheckCancelled(); 
     if (IsCancelled) 
     { 
      throw new JsonReaderCancelledException(); 
     } 
    } 
} 

public class JsonReaderCancelledException : JsonReaderException 
{ 
    public JsonReaderCancelledException() { } 

    public JsonReaderCancelledException(string message) 
     : base(message) 
    { 
    } 

    public JsonReaderCancelledException(string message, Exception innerException) 
     : base(message, innerException) 
    { 
    } 

    public JsonReaderCancelledException(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 
} 

Ve sonra ister kullanın: kendiniz yapmak

public static T Parse<T>(Stream stream, Func<bool> checkCancelled) 
    { 
     var serializer = new JsonSerializer(); 
     using (var sr = new StreamReader(stream)) 
     using (var jsonTextReader = new CancellableJsonTextReader(sr, checkCancelled)) 
     { 
      var result = serializer.Deserialize<T>(jsonTextReader); 
      return result; 
     } 
    } 

sonra daha yüksek bir kod seviyesinde, JsonReaderCancelledException durum yakalamak.

Not: checkCancelled yönteminiz başka bir iş parçacığı için ayarlanmış bir bool işaretliyorsa, volatile olarak bildirmeniz gerekir. Bakınız Is it safe to use a boolean flag to stop a thread from running in C#.

Performansı üretime sokmadan önce denemek istiyorum. Her okuma için checkCancelled delege çağırıyorsanız, her 10 veya 100 okuma için bunu yapabilirsiniz.

0

sizin serileştirici iptal desteklemiyorsa, bunun yerine aşağıdakileri yapabilirsiniz: Verileri

Ör getirir üst tabakasında

İlgili konular