using System.Diagnostics;
using System.IO;
using System.Text;
-#if !NET_2_1
using System.Xml.Schema; // only required for NET_2_0 (SchemaInfo)
using System.Xml.Serialization; // only required for NET_2_0 (SchemaInfo)
using Mono.Xml.Schema; // only required for NET_2_0
-#endif
using Mono.Xml; // only required for NET_2_0
+#if NET_4_5
+using System.Threading;
+using System.Threading.Tasks;
+#endif
namespace System.Xml
{
get { return AttributeCount > 0; }
}
-#if !NET_2_1
+#if NET_4_0
+ public virtual bool HasValue {
+ get {
+ switch (NodeType) {
+ case XmlNodeType.Attribute:
+ case XmlNodeType.Comment:
+ case XmlNodeType.ProcessingInstruction:
+ case XmlNodeType.SignificantWhitespace:
+ case XmlNodeType.CDATA:
+ case XmlNodeType.Text:
+ case XmlNodeType.Whitespace:
+ case XmlNodeType.XmlDeclaration:
+ return true;
+ }
+ return false;
+ }
+ }
+#else
public abstract bool HasValue { get; }
#endif
public abstract ReadState ReadState { get; }
#if NET_2_0
-#if !NET_2_1
public virtual IXmlSchemaInfo SchemaInfo {
get { return null; }
}
-#endif
public virtual XmlReaderSettings Settings {
get { return settings; }
#region Methods
+#if NET_4_5
+ public virtual void Close ()
+ {
+ if (asyncRunning)
+ throw new InvalidOperationException ("An asynchronous operation is already in progress.");
+ }
+#else
public abstract void Close ();
+#endif
#if NET_2_0
private static XmlNameTable PopulateNameTable (
XmlNodeType.Document;
}
- public static XmlReader Create (Stream stream)
+ public static XmlReader Create (Stream input)
{
- return Create (stream, null);
+ return Create (input, null);
}
- public static XmlReader Create (string url)
+ public static XmlReader Create (string inputUri)
{
- return Create (url, null);
+ return Create (inputUri, null);
}
- public static XmlReader Create (TextReader reader)
+ public static XmlReader Create (TextReader input)
{
- return Create (reader, null);
+ return Create (input, null);
}
- public static XmlReader Create (string url, XmlReaderSettings settings)
+ public static XmlReader Create (string inputUri, XmlReaderSettings settings)
{
- return Create (url, settings, null);
+ return Create (inputUri, settings, null);
}
- public static XmlReader Create (Stream stream, XmlReaderSettings settings)
+ public static XmlReader Create (Stream input, XmlReaderSettings settings)
{
- return Create (stream, settings, String.Empty);
+ return Create (input, settings, String.Empty);
}
- public static XmlReader Create (TextReader reader, XmlReaderSettings settings)
+ public static XmlReader Create (TextReader input, XmlReaderSettings settings)
{
- return Create (reader, settings, String.Empty);
+ return Create (input, settings, String.Empty);
}
static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
{
+ XmlReaderSettings copy;
if (src == null)
- return new XmlReaderSettings ();
+ copy = new XmlReaderSettings ();
else
- return src.Clone ();
+ copy = src.Clone ();
+#if NET_4_5
+ copy.SetReadOnly ();
+#endif
+ return copy;
}
- public static XmlReader Create (Stream stream, XmlReaderSettings settings, string baseUri)
+ static XmlReaderSettings PopulateSettings (XmlReader reader, XmlReaderSettings src)
+ {
+ XmlReaderSettings copy;
+ if (src == null)
+ copy = new XmlReaderSettings ();
+ else
+ copy = src.Clone ();
+#if NET_4_5
+ if (reader.Settings != null)
+ copy.Async = reader.Settings.Async;
+ copy.SetReadOnly ();
+#endif
+ return copy;
+ }
+
+ public static XmlReader Create (Stream input, XmlReaderSettings settings, string baseUri)
{
settings = PopulateSettings (settings);
- return Create (stream, settings,
+ return Create (input, settings,
PopulateParserContext (settings, baseUri));
}
- public static XmlReader Create (TextReader reader, XmlReaderSettings settings, string baseUri)
+ public static XmlReader Create (TextReader input, XmlReaderSettings settings, string baseUri)
{
settings = PopulateSettings (settings);
- return Create (reader, settings,
+ return Create (input, settings,
PopulateParserContext (settings, baseUri));
}
public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
{
- settings = PopulateSettings (settings);
+ settings = PopulateSettings (reader, settings);
XmlReader r = CreateFilteredXmlReader (reader, settings);
r.settings = settings;
return r;
}
- public static XmlReader Create (string url, XmlReaderSettings settings, XmlParserContext context)
+ public static XmlReader Create (string inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
{
settings = PopulateSettings (settings);
bool closeInputBak = settings.CloseInput;
try {
settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
- if (context == null)
- context = PopulateParserContext (settings, url);
- XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, url, GetNodeType (settings), context);
+ if (inputContext == null)
+ inputContext = PopulateParserContext (settings, inputUri);
+ XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, inputUri, GetNodeType (settings), inputContext);
XmlReader ret = CreateCustomizedTextReader (xtr, settings);
return ret;
} finally {
}
}
- public static XmlReader Create (Stream stream, XmlReaderSettings settings, XmlParserContext context)
+ public static XmlReader Create (Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
{
settings = PopulateSettings (settings);
- if (context == null)
- context = PopulateParserContext (settings, String.Empty);
- return CreateCustomizedTextReader (new XmlTextReader (stream, GetNodeType (settings), context), settings);
+ if (inputContext == null)
+ inputContext = PopulateParserContext (settings, String.Empty);
+ return CreateCustomizedTextReader (new XmlTextReader (input, GetNodeType (settings), inputContext), settings);
}
- public static XmlReader Create (TextReader reader, XmlReaderSettings settings, XmlParserContext context)
+ public static XmlReader Create (TextReader input, XmlReaderSettings settings, XmlParserContext inputContext)
{
settings = PopulateSettings (settings);
- if (context == null)
- context = PopulateParserContext (settings, String.Empty);
- return CreateCustomizedTextReader (new XmlTextReader (context.BaseURI, reader, GetNodeType (settings), context), settings);
+ if (inputContext == null)
+ inputContext = PopulateParserContext (settings, String.Empty);
+ return CreateCustomizedTextReader (new XmlTextReader (inputContext.BaseURI, input, GetNodeType (settings), inputContext), settings);
}
private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
{
-#if NET_2_1
- return reader;
-#else
XmlValidatingReader xvr = null;
switch (settings.ValidationType) {
// Auto and XDR are obsoleted in 2.0 and therefore ignored.
// throw new NotImplementedException ();
return xvr != null ? xvr : reader;
-#endif
}
- void IDisposable.Dispose ()
+#if NET_4_0
+ public void Dispose ()
+#else
+ void IDisposable.Dispose()
+#endif
{
Dispose (false);
}
public abstract string GetAttribute (string name);
- public abstract string GetAttribute (
- string localName,
- string namespaceName);
+ public abstract string GetAttribute (string name, string namespaceURI);
- public static bool IsName (string s)
+ public static bool IsName (string str)
{
- return s != null && XmlChar.IsName (s);
+ return str != null && XmlChar.IsName (str);
}
- public static bool IsNameToken (string s)
+ public static bool IsNameToken (string str)
{
- return s != null && XmlChar.IsNmToken (s);
+ return str != null && XmlChar.IsNmToken (str);
}
public virtual bool IsStartElement ()
return (Name == name);
}
- public virtual bool IsStartElement (string localName, string namespaceName)
+ public virtual bool IsStartElement (string localname, string ns)
{
if (!IsStartElement ())
return false;
- return (LocalName == localName && NamespaceURI == namespaceName);
+ return (LocalName == localname && NamespaceURI == ns);
}
public abstract string LookupNamespace (string prefix);
public abstract bool MoveToAttribute (string name);
- public abstract bool MoveToAttribute (
- string localName,
- string namespaceName);
+ public abstract bool MoveToAttribute (string name, string ns);
private bool IsContent (XmlNodeType nodeType)
{
public virtual XmlNodeType MoveToContent ()
{
+ switch (ReadState) {
+ case ReadState.Initial:
+ case ReadState.Interactive:
+ break;
+ default:
+ return NodeType;
+ }
+
if (NodeType == XmlNodeType.Attribute)
MoveToElement ();
public abstract bool Read ();
-#if !NET_2_1
public abstract bool ReadAttributeValue ();
-#endif
public virtual string ReadElementString ()
{
return result;
}
- public virtual string ReadElementString (string localName, string namespaceName)
+ public virtual string ReadElementString (string localname, string ns)
{
if (MoveToContent () != XmlNodeType.Element) {
string error = String.Format ("'{0}' is an invalid node type.",
throw XmlError (error);
}
- if (localName != LocalName || NamespaceURI != namespaceName) {
+ if (localname != LocalName || NamespaceURI != ns) {
string error = String.Format ("The {0} tag from namespace {1} is expected.",
LocalName, NamespaceURI);
throw XmlError (error);
Read ();
}
- public virtual void ReadStartElement (string localName, string namespaceName)
+ public virtual void ReadStartElement (string localname, string ns)
{
if (MoveToContent () != XmlNodeType.Element) {
string error = String.Format ("'{0}' is an invalid node type.",
throw XmlError (error);
}
- if (localName != LocalName || NamespaceURI != namespaceName) {
+ if (localname != LocalName || NamespaceURI != ns) {
string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
- localName, namespaceName,
+ localname, ns,
LocalName, NamespaceURI);
throw XmlError (error);
}
public virtual bool ReadToFollowing (string localName, string namespaceURI)
{
while (Read ())
- if (NodeType == XmlNodeType.Element && localName == Name && namespaceURI == NamespaceURI)
+ if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
return true;
return false;
}
{
if (ReadState != ReadState.Interactive)
return false;
+ MoveToElement ();
int depth = Depth;
Skip ();
for (; !EOF && depth <= Depth; Skip ())
public virtual XmlReader ReadSubtree ()
{
+ if (NodeType != XmlNodeType.Element)
+ throw new InvalidOperationException (String.Format ("ReadSubtree() can be invoked only when the reader is positioned on an element. Current node is {0}. {1}", NodeType, GetLocation ()));
return new SubtreeXmlReader (this);
}
private string ReadContentString ()
{
- if (NodeType == XmlNodeType.Attribute)
+ // The latter condition indicates that this XmlReader is on an attribute value
+ // (HasAttributes is to indicate it is on attribute value).
+ if (NodeType == XmlNodeType.Attribute || NodeType != XmlNodeType.Element && HasAttributes)
return Value;
return ReadContentString (true);
}
case XmlNodeType.Whitespace:
case XmlNodeType.CDATA:
break;
- default:
+ case XmlNodeType.Element:
throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
+ default:
+ return String.Empty;
}
}
return ReadContentAs (ValueType, null);
}
- public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver)
+#if NET_4_5
+ public virtual DateTimeOffset ReadContentAsDateTimeOffset ()
+ {
+ try {
+ return XmlConvert.ToDateTimeOffset (ReadContentString ());
+ } catch (Exception e) {
+ throw XmlError ("Typed value is invalid.", e);
+ }
+ }
+#endif
+
+ public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
{
bool isEmpty = IsEmptyElement;
ReadStartElement ();
- object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), type, resolver);
+ object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), returnType, namespaceResolver, false);
if (!isEmpty)
ReadEndElement ();
return obj;
}
- public virtual object ReadElementContentAs (Type type, IXmlNamespaceResolver resolver, string localName, string namespaceURI)
+ public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver, string localName, string namespaceURI)
{
+ if (localName == null)
+ throw new ArgumentNullException ("localName");
+ if (namespaceURI == null)
+ throw new ArgumentNullException ("namespaceURI");
+
+ bool isEmpty = IsEmptyElement;
ReadStartElement (localName, namespaceURI);
- object obj = ReadContentAs (type, resolver);
+ if (isEmpty)
+ return ValueAs (String.Empty, returnType, namespaceResolver, false);
+ object obj = ReadContentAs (returnType, namespaceResolver);
ReadEndElement ();
return obj;
}
- public virtual object ReadContentAs (Type type, IXmlNamespaceResolver resolver)
+ public virtual object ReadContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
{
- return ValueAs (ReadContentString (), type, resolver);
+ return ValueAs (ReadContentString (), returnType, namespaceResolver, false);
}
- private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver)
+ private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver, bool isArrayItem)
{
try {
if (type == typeof (object))
return text;
+ if (type.IsArray && !isArrayItem) {
+ var elemType = type.GetElementType ();
+ var sarr = text.Split ((string []) null, StringSplitOptions.RemoveEmptyEntries);
+ var ret = Array.CreateInstance (elemType, sarr.Length);
+ for (int i = 0; i < ret.Length; i++)
+ ret.SetValue (ValueAs (sarr [i], elemType, resolver, true), i);
+ return ret;
+ }
+
if (type == typeof (XmlQualifiedName)) {
if (resolver != null)
- return XmlQualifiedName.Parse (text, resolver);
+ return XmlQualifiedName.Parse (text, resolver, true);
else
- return XmlQualifiedName.Parse (text, this);
+ return XmlQualifiedName.Parse (text, this, true);
}
+ if (type == typeof (Uri))
+ return XmlConvert.ToUri (text);
+ if (type == typeof (TimeSpan))
+ return XmlConvert.ToTimeSpan (text);
+ if (type == typeof (DateTimeOffset))
+ return XmlConvert.ToDateTimeOffset (text);
switch (Type.GetTypeCode (type)) {
case TypeCode.Boolean:
return XQueryConvert.StringToBoolean (text);
+ case TypeCode.Byte:
+ return XmlConvert.ToByte (text);
+ case TypeCode.SByte:
+ return XmlConvert.ToSByte (text);
+ case TypeCode.Int16:
+ return XmlConvert.ToInt16 (text);
+ case TypeCode.UInt16:
+ return XQueryConvert.StringToUnsignedShort (text);
+ case TypeCode.Int32:
+ return XQueryConvert.StringToInt (text);
+ case TypeCode.UInt32:
+ return XQueryConvert.StringToUnsignedInt (text);
+ case TypeCode.Int64:
+ return XQueryConvert.StringToInteger (text);
+ case TypeCode.UInt64:
+ return XQueryConvert.StringToUnsignedLong (text);
case TypeCode.DateTime:
return XQueryConvert.StringToDateTime (text);
case TypeCode.Decimal:
return XQueryConvert.StringToDecimal (text);
case TypeCode.Double:
return XQueryConvert.StringToDouble (text);
- case TypeCode.Int32:
- return XQueryConvert.StringToInt (text);
- case TypeCode.Int64:
- return XQueryConvert.StringToInteger (text);
case TypeCode.Single:
return XQueryConvert.StringToFloat (text);
case TypeCode.String:
} catch (Exception ex) {
throw XmlError (String.Format ("Current text value '{0}' is not acceptable for specified type '{1}'. {2}", text, type, ex != null ? ex.Message : String.Empty), ex);
}
- throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
+ throw new XmlException (String.Format ("Specified type '{0}' is not supported.", type));
}
public virtual bool ReadElementContentAsBoolean ()
public virtual string ReadElementContentAsString ()
{
bool isEmpty = IsEmptyElement;
+ // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
+ if (NodeType != XmlNodeType.Element)
+ throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
ReadStartElement ();
if (isEmpty)
return String.Empty;
public virtual string ReadElementContentAsString (string localName, string namespaceURI)
{
bool isEmpty = IsEmptyElement;
+ // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
+ if (NodeType != XmlNodeType.Element)
+ throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
ReadStartElement (localName, namespaceURI);
if (isEmpty)
return String.Empty;
}
public virtual int ReadContentAsBase64 (
- byte [] buffer, int offset, int length)
+ byte [] buffer, int index, int count)
{
CheckSupport ();
return binary.ReadContentAsBase64 (
- buffer, offset, length);
+ buffer, index, count);
}
public virtual int ReadContentAsBinHex (
- byte [] buffer, int offset, int length)
+ byte [] buffer, int index, int count)
{
CheckSupport ();
return binary.ReadContentAsBinHex (
- buffer, offset, length);
+ buffer, index, count);
}
public virtual int ReadElementContentAsBase64 (
- byte [] buffer, int offset, int length)
+ byte [] buffer, int index, int count)
{
CheckSupport ();
return binary.ReadElementContentAsBase64 (
- buffer, offset, length);
+ buffer, index, count);
}
public virtual int ReadElementContentAsBinHex (
- byte [] buffer, int offset, int length)
+ byte [] buffer, int index, int count)
{
CheckSupport ();
return binary.ReadElementContentAsBinHex (
- buffer, offset, length);
+ buffer, index, count);
}
-#endif
-#if NET_2_0
- public virtual int ReadValueChunk (
- char [] buffer, int offset, int length)
-#else
- internal virtual int ReadValueChunk (
- char [] buffer, int offset, int length)
-#endif
+ private void CheckSupport ()
{
- if (!CanReadValueChunk)
+ // Default implementation expects both.
+ if (!CanReadBinaryContent || !CanReadValueChunk)
throw new NotSupportedException ();
if (binary == null)
binary = new XmlReaderBinarySupport (this);
- return binary.ReadValueChunk (buffer, offset, length);
}
+
+#endif
- private void CheckSupport ()
+ public virtual int ReadValueChunk (char [] buffer, int index, int count)
{
- // Default implementation expects both.
- if (!CanReadBinaryContent || !CanReadValueChunk)
+ if (!CanReadValueChunk)
throw new NotSupportedException ();
if (binary == null)
binary = new XmlReaderBinarySupport (this);
+ return binary.ReadValueChunk (buffer, index, count);
}
public abstract void ResolveEntity ();
{
return new XmlException (this as IXmlLineInfo, BaseURI, message);
}
-
+#if NET_2_0
private XmlException XmlError (string message, Exception innerException)
{
return new XmlException (this as IXmlLineInfo, BaseURI, message);
}
+#endif
+ #endregion
+
+#if NET_4_5
+ #region .NET 4.5 Async Methods
+
+ bool asyncRunning;
+
+ void StartAsync ()
+ {
+ if (!settings.Async)
+ throw new InvalidOperationException ("Set XmlReaderSettings.Async to true if you want to use Async Methods.");
+ lock (this) {
+ if (asyncRunning)
+ throw new InvalidOperationException ("An asynchronous operation is already in progress.");
+ asyncRunning = true;
+ }
+ }
+
+ public virtual Task<bool> ReadAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return Read ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<string> GetValueAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return Value;
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<string> ReadInnerXmlAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadInnerXml ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<string> ReadOuterXmlAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadOuterXml ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<string> ReadContentAsStringAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadContentAsString ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<int> ReadContentAsBase64Async (byte[] buffer, int index, int count)
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadContentAsBase64 (buffer, index, count);
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<int> ReadContentAsBinHexAsync (byte[] buffer, int index, int count)
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadContentAsBinHex (buffer, index, count);
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<int> ReadElementContentAsBase64Async (byte[] buffer, int index, int count)
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadElementContentAsBase64 (buffer, index, count);
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<int> ReadElementContentAsBinHexAsync (byte[] buffer, int index, int count)
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadElementContentAsBinHex (buffer, index, count);
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<int> ReadValueChunkAsync (char[] buffer, int index, int count)
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadValueChunk (buffer, index, count);
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<object> ReadContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadContentAs (returnType, namespaceResolver);
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<object> ReadContentAsObjectAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadContentAsObject ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<object> ReadElementContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadElementContentAs (returnType, namespaceResolver);
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<object> ReadElementContentAsObjectAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadElementContentAsObject ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<string> ReadElementContentAsStringAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return ReadElementContentAsString ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task<XmlNodeType> MoveToContentAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ return MoveToContent ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
+
+ public virtual Task SkipAsync ()
+ {
+ StartAsync ();
+ return Task.Run (() => {
+ try {
+ Skip ();
+ } finally {
+ asyncRunning = false;
+ }
+ });
+ }
#endregion
+#endif
}
}