views:

104

answers:

3

The following is in C#.

I'm trying to do something very simple (I think). I have a method that loads an XML document

XDocument  doc = XDocument.Load(uri);

, but I don't want to tie up pc resources if there are issues (connectivity, document size, etc.).

So I'd like to be able to add a timeout variable that will cut the method off after a given number of seconds. I'm a newbie when it comes to asynchronous programming and find it confusing that there are so many examples written so many different ways . . . and none of them appear simple. I'd like a simple solution, if possible.

Here's my thoughts so far on possible solution paths:

1) A method that wraps the existing load

public XDocument LoadXDocument(string uri, int timeout){ //code }

2) A wrapper, but as an extension method

XDocument doc = XDocument.LoadWithTimeout(string uri, int timeout);

3) A generic extension method.

Object obj = SomeStaticClass.LoadWithTimeout(??? method, int timeout);

3), on its face seems really nice, because it would mean being able to generically add timeouts to many different method calls and not specifically tied to one type of object, but I suspect that it is either i)impossible or ii) very difficult.

Please assist. Thanks.

+1  A: 

Similar question here: http://stackoverflow.com/questions/299198/implement-c-generic-timeout

mwilson
Many different answers with the accepted answer being noted as dangerous. Did you have a preference?
John
A: 

is this Windows or Web ? Please retag.

If windows, why don't you use a Background Worker for executing that method in a different thread than the main one? and use a progress bar for example to let user know that it is working... when done, alert the user if needed.

in Web I would do the same thing, just add the method into a brand new page and then using jQuery for example, use $.get to run the method asynchronously

or I'm missing something?


from mwilson answer I think you want to really force a timeout rather than use the internal timeout/error of the method.

Rather than delete my answer I will let it be as someone could use it.

balexandre
What are you referring to when you say "force a timeout rather than use the internal timeout/error"? Is the answer by Tsiokos an example?
John
A: 

This should give you a nice starting point.

public static XDocument GetDoc(string uri, int timeout)
{
    var result = default(XDocument);
    {
        using (var client = new WebClient())
        using (var complete = new ManualResetEvent(false))
        {
            client.DownloadStringCompleted += (sender, e) =>
            {
                try
                {
                    if (!e.Cancelled)
                    {
                        result = XDocument.Parse(e.Result);
                    }
                }
                finally
                {
                    complete.Set();
                }
            };

            client.DownloadStringAsync(new Uri(uri));
            Thread.Sleep(timeout);
            if (!complete.WaitOne(1))
            {
                client.CancelAsync();
            }
            complete.WaitOne();
        }
    }
    return result;
}
ChaosPandion