How to stop the black box operation?

I use an asynchronous delegate that calls a method that loads an XML file into XPathDocument. If xml is too big to fit in memory, it never finishes loading. The code below works if the XML file is successfully loaded into XPathDocument. I was able to use a timer event that executes the asyncXpath.EndInvoke (result) statement, and this works to end the CreateDocument method, but it does not stop loading XPathDocument. I came to the conclusion that the only thing I can do is to issue an Application.End expression to kill the application. Does anyone know how to stop a Blackbox operation such as loading XPathDocument.

delegate bool AsyncXpathQueryCaller(string xmlfile bool found = false; AsyncXpathQueryCaller asyncXpath = new AsyncXpathQueryCaller(CreateDocument); IAsyncResult result = asyncXpath.BeginInvoke(xmlfile, null, null); while (!result.IsCompleted) { result.AsyncWaitHandle.WaitOne(100, false); } found = asyncXpath.EndInvoke(result); private bool CreateDocument (string xmlfile) { XPathDocument doc = new XPathDocument(xmlfile); } 
+4
source share
4 answers

How about using FileInfo before trying to download it and check the size? If it is too big, just skip it.

Something like that:

 FileInfo fi = new FileInfo(xmlfile); if(fi.Length < /*some huge number*/) { //load the file } 
+1
source

You can declare a FileStream and pass it to the constructor, but before you do that, look at its Length property, and if it's too long, just return an error.

0
source

EDIT : I just realized that KeithS was approaching a good answer. The basic idea is that you call the XPathDocument constructor , which takes a Stream , which wraps a FileStream . The object you pass must implement the Read(byte[], int, int) function Read(byte[], int, int) to call the wrapped FileStream Read function, or throw an exception if the operation has been disabled. Here is a sample code:

 class XmlStream : FileStream { DateTime deadline; public XmlStream(string filename, TimeSpan timeout) : base(filename, FileMode.Open) { deadline = DateTime.UtcNow + timeout; } public override int Read(byte[] array, int offset, int count) { if (DateTime.UtcNow > deadline) throw new TimeoutException(); return base.Read(array, offset, count); } } 

Here is the code that reads in document but expires in 1 second:

  bool found = true; using(var stream = new XmlStream(document, TimeSpan.FromSeconds(1))) try { xpath = new XPathDocument(stream); } catch (TimeoutException) { found = false; } 

If you create a separate thread instead of executing BeginInvoke , you can simply interrupt the thread when the timer BeginInvoke (or someone clicks Cancel). Although thread interruption is usually impractical because it can hold a lock or have global data in an inconsistent state, in this case it should be good because your thread will not hold a lock or global data.

Here is the code for this method, which does the same as the previous sample:

  bool found = false; thread = new Thread(() => { xpath = new XPathDocument(document); found = true; }); thread.Start(); thread.Join(TimeSpan.FromSeconds(1)); thread.Abort(); 

If you are not comfortable interrupting threads in your own application domain, you can create a document in another application domain and call AppDomain.Unload if it takes too much time. This will require some sorting, but there probably won't be too much overhead.

The ultimate way to kill a process is to run it in a separate process and use some kind of remote access interface to access it. Probably even more erratic than other parameters, however, since you have to worry about finding the executable, passing parameters, some users completing it, etc.

0
source

As suggested by Abe Miessler, it is wise to check the file size before it is loaded into XPathDocument.

How to decide what should be the limit ?

There is no exact rule, but I heard that people say that you should multiply the file size by 5, and then the result is close to the memory that XmlDocument will require in order for the text to be loaded / processed.

0
source

Source: https://habr.com/ru/post/1339290/


All Articles