JsonTextReader
不支持這個開箱即用,但Json.NET不正確地處理(即重新拋出)例外,從較低級代碼來了,所以你可以繼承讀者和自己動手:
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)
{
}
}
,然後用它喜歡:
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;
}
}
然後,在更高的代碼級別,捕捉JsonReaderCancelledException
例外。
請注意,如果您的checkCancelled
方法正在檢查可能在另一個線程中設置的bool
標誌,則必須將其聲明爲volatile
。見Is it safe to use a boolean flag to stop a thread from running in C#。
您希望在投入生產之前測試性能。如果爲每次讀取調用checkCancelled
代表不能執行,則可以每10或100次讀取一次。
來源
2016-04-14 18:24:20
dbc
不完全確定我明白你想要做什麼。如果您使用單線程運行,用戶將如何取消?如果使用多個線程(在.net 3.5中)運行,爲什麼不使用['BackgroundWorker'](https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v = vs.90))。 ASPX)?另見https://msdn.microsoft.com/en-us/library/ywkkz4s1%28v=vs.100%29.aspx – dbc