Thread: Timing and Ending a Function

  1. #1
    Registered User mikeman118's Avatar
    Join Date
    Aug 2007
    Posts
    183

    Timing and Ending a Function

    Hi,

    I have a function which is downloads a web page for something, which can sometimes take a long time. I would like to be able to time the function, and when it goes past the time limit it would stop it. What I was thinking of doing was setting a timer and when the timer went off, it would stop the function. My question is, how would I stop the function? Or is there a better way? Thanks.

  2. #2
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    create the function as a new thread (CreateThread/_beginthreadex). have the thread create an event (CreateEvent) in the non-signalled state. once the thread is finished doing whatever it has to do, have it set the event (SetEvent) to the signalled state. this way, from outside the thread you can call WaitForSingleObject on the event handle, and stop the thread (SuspendThread) if x time has elapsed and the event is still not signalled.
    Last edited by Bleech; 12-19-2007 at 04:42 PM. Reason: typo

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Which is relatively easy, because WaitForSingleObject() will take a timeout parameter in milliseconds, so you can set it to whatever amount of time you expect it to take, and if it comes back with a "timeout", you know that the thread didn't complete in time.

    Unfortunately, you have no way to actually kill the thread itself nicely, so you will have to let the thread kill itself [there is a TerminateThread() function, but MS says that this leaks the original stack of the thread, which means that it's bad to use this on long-running processes].

    Another option is to use "overlapped", aka "asynchronous" read/write functions, and use CancleIO when the thread fails to complete the read - unfortunately, this is also quite complex when you mix it with sockets and such.

    Perhaps it's better to start a different PROCESS and let the timeout terminate the process.

    Sorry for the rambling and "discovery" type answer - I'm just looking this up as I write.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    What is the function? There may be an asynchronous version that can be canceled safely.

    gg

  5. #5
    Registered User mikeman118's Avatar
    Join Date
    Aug 2007
    Posts
    183
    Thanks everyone, I'll look into this and come back in a little while.
    @ Codeplug
    I was using the disphelper library's Donwnload Web Page function. More specifically:
    Code:
    void DownloadWebPage(LPCTSTR szURL)
    {
        CDispPtr objHTTP;
        CDhStringA szResponse, szStatus;
     
        try
        {
            ofstream os("file.txt");
            dhCheck( dhCreateObject(L"MSXML2.XMLHTTP", NULL, &objHTTP) );
            dhCheck( dhCallMethod(objHTTP, L".Open(%S, %T, %b)", L"GET", szURL, FALSE) );
            dhCheck( dhCallMethod(objHTTP, L".Send") );
     
            dhCheck( dhGetValue(L"%s", &szStatus, objHTTP, L".StatusText") );
            cout << "Status: " << szStatus << endl;
     
            dhCheck( dhGetValue(L"%s", &szResponse, objHTTP, L".ResponseText") );
            os << szResponse;
        }
        catch (string errstr)
        {
            cerr << "Fatal error details:" << endl << errstr << endl;
        }
    }
    I don't know if that's the best way, as it sometimes is slow. Does anyone know a better way? Thanks.

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> dhCheck( dhCallMethod(objHTTP, L".Open(%S, %T, %b)", L"GET", szURL, FALSE) );

    The parameter in red is the "asynchronous" flag.
    Quote Originally Posted by MSDN
    varAsync[optional]
    A Boolean indicator of whether the call is asynchronous. The default is True (the call returns immediately). If set to True, attach an onreadystatechange property callback so that you can tell when the send call has completed.
    However.....
    Quote Originally Posted by MSDN
    Because the onreadystatechange property was not implemented through COM-based automation events, Visual Basic (and C/C++) applications need to implement this callback functionality differently.
    Quote Originally Posted by MSDN
    In C++, use connection points to trap all XMLDOMDocument events. The DISPID of the connection point container is DIID_XMLDOMDocumentEvents. The DISPID for the connection point to trap the readystatechange event is DISPID_XMLDOMEVENT_ONREADYSTATECHANGE.
    How you do this using DispHelper is beyond me. If you want to keep this simple without doing much R&D, you could move DownloadWebPage() into it's own process. Then you could kill the process if it's taking too long - which is *much* safer than TerminateThread(). The downside of this is the overhead associated with creating a process.

    >> Does anyone know a better way?
    Looks to me like you're just doing a GET on a URL - in which case you could use the GNU tool WGet as the DownloadWebPage() process. There are other COM API's for performing simple GET's if you would prefer to keep everything in one process. But if you're not familiar with COM and DispHelper, this route may be more R&D than it's worth - but you gotta learn somehow

    A common COM API for HTTP is "WinHTTP": http://msdn2.microsoft.com/en-us/library/aa384273.aspx

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Counter (Time)
    By PickleBranston in forum C Programming
    Replies: 16
    Last Post: 02-10-2009, 01:00 PM
  2. timing accuracy?
    By mfknitz in forum C++ Programming
    Replies: 13
    Last Post: 07-16-2003, 04:22 PM