Reputation: 41
I am trying to timeout and throw an exception after waiting a specified amount of time, and am wondering if the way I'm currently doing it is best.
class Timeout
{
XmlDocument doc;
System.Object input;
public Timeout(XmlDocument doc, System.Object input)
{
this.doc = doc;
this.input = input;
}
public void run()
{
if (input is Stream)
{
doc.Load((Stream)input);
}
else if (input is XmlReader)
{
doc.Load((XmlReader)input);
}
else if (input is TextReader)
{
doc.Load((TextReader)input);
}
else
{
doc.Load((string)input);
}
System.Threading.Thread.CurrentThread.Abort();
}
}
private void LoadXmlDoc(XmlDocument doc, System.Object input)
{
Timeout timeout = new Timeout(doc, input);
System.Threading.Thread timeoutThread = new System.Threading.Thread(new ThreadStart(timeout.run));
timeoutThread.Start();
System.Threading.Thread.Sleep(this.timeout * 1000);
if (timeoutThread.IsAlive)
{
throw new DataSourceException("timeout reached", timeout.GetHashCode());
}
}
This current approach does work, so I'm just wondering if there's a simpler/better way to go about accomplishing the same thing.
Upvotes: 3
Views: 2379
Reputation: 41
What I ended up doing:
class Timeout
{
XmlDocument doc;
System.Object input;
public Timeout(XmlDocument doc, System.Object input)
{
this.doc = doc;
this.input = input;
}
public void run()
{
if (input is Stream)
{
doc.Load((Stream)input);
}
else if (input is XmlReader)
{
doc.Load((XmlReader)input);
}
else if (input is TextReader)
{
doc.Load((TextReader)input);
}
else
{
doc.Load((string)input);
}
}
}
private void LoadXmlDoc(XmlDocument doc, System.Object input)
{
Timeout timeout = new Timeout(doc, input);
System.Threading.Thread timeoutThread = new System.Threading.Thread(new ThreadStart(timeout.run));
timeoutThread.Name = "XmlWorker" + threadNumber++;
timeoutThread.Start();
if (!timeoutThread.Join(this.timeout)) //Join returning false implies the timeout was reached
{
if (timeoutThread.IsAlive)
timeoutThread.Abort();
throw new DataConnectionException("timeout reached: " + this.timeout.Milliseconds + "ms", new TimeoutException(this.timeout.Milliseconds));
}
}
Upvotes: 1
Reputation: 884
Try doing something like this:
try
{
var cts = new System.Threading.CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(0.01));
var tw = Task.Run<System.Xml.XmlDocument>(() =>
{
var doc = new System.Xml.XmlDocument();
doc.Load("https://maps.googleapis.com/maps/api/geocode/xml?address=1+Exchange+Plaza+,+Floor+26+,+NY&sensor=false");
return doc;
}, cts.Token);
var xml = await tw;
}
catch (TaskCanceledException e)
{
}
Upvotes: 3
Reputation: 495
In addition to my comment (here's the link from it), here is some more information regarding threading. Basically it comes down to learning the different designs/libraries, what their pros and cons are, which one suits your needs best.
From my understanding, and hopefully someone with more knowledge on the subject will pitch in on this, there are basically 2 different categories that you can put the threading designs in, synchronous and asynchronous. You have used the asynchronous design, employing the thread pool. If you want to stick with this design, you can try using the Task
or, for synchronous operations Parallel
.
On a side note: I'm not sure as to the wisdom behind using an exception to handle simple logic. In other words, the exception
could be simply replace with returning a boolean
.
Upvotes: 1