Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

timed polling of a database in a W2K service

Posted on 2002-03-31
21
254 Views
Last Modified: 2010-04-02
Using the ATL Wizard in VC++6 I've created a service.  I'm guessing that my code has to go in the run() method.

My first question is:

If all I want my service to do is after a set time interval get some data from the database.  How do I loop?
If I put a while loop in the run method then i will effectively lock the service from communicating with the SCM.

Any help or small examples would be great, I do have a book on it but as of yet I've not found anything regarding this, and I am pushed for time.

Second question:
Can ATL system services support MFC class usage?
0
Comment
Question by:MattC
  • 8
  • 6
  • 3
  • +2
21 Comments
 
LVL 22

Accepted Solution

by:
cookre earned 150 total points
ID: 6909448
There are several ways:
Use a timer to activate a function at a specified interval:


#define    MonitorID 1
UINT       MonitorTimer;

MonitorTimer=SetTimer(hWnd
                     ,MonitorID
                     ,10000     // (10 second interval)
                     ,(TIMERPROC)NSEMonitor);


void CALLBACK NSEMonitor(HWND hwnd
                        ,UINT uMsg
                        ,UINT_PTR idEvent
                        ,DWORD dwTime)
With this method, your program can go about others chores and the call back proc will be triggered at the specified intervals.



The other way is with a simple Sleep():

Sleep(2000);

This will pause the entire process, but won't effect the performance of the OS.
0
 
LVL 1

Author Comment

by:MattC
ID: 6909457
i thought about starting a worker thread in Run() then making that a while(SERVICE_RUNNING) and then at the top of the while do a Sleep(300000) so each time round it waits 300 seconds before going round again.
0
 
LVL 1

Author Comment

by:MattC
ID: 6909460
oops that should be:

while(_Module.m_status = SERVICE_RUNNING){
   Sleep(300000);

   //do code here
}
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 22

Expert Comment

by:cookre
ID: 6909498
Sounds reasonable, as long as you don't need to be doing anything else at the time (including message processing).
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6910931
>>Can ATL system services support MFC class usage?

When you create the service, the AppWizard presents that as an option.  There is a "Support MFC" checkbox.

-- Dan
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6911002
oops, I see that the Support MFC checkbox gets dimmed when you select the Service radio button.  Looking at my code, for a service that uses MFC, I see that I needed to add some headers to StdAfx.h:

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions

I also see that for some reason I have this in the InitInstance:

    afxContextIsDLL= FALSE;

Alas, I did not comment the reason for that code!
-- Dan
0
 
LVL 86

Expert Comment

by:jkr
ID: 6913754
Why don't you just kick off a separate thread from the service in order to do the polling work - it could be as simple as

long WINAPI TimerThread ( LPVOID pv) {

DWORD dwWait = ( DWORD) pv,

for ( ;;) {

 Sleep ( dwWait);

 // do work here...
}
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 6913758
BTW, if you'd like something more sophisticated than the above, check out http://support.microsoft.com/support/kb/articles/q184/7/96.asp ("HOWTO: Use a Waitable Timer with an Asynchronous Procedure Call (Q184796)") and http://msdn.microsoft.com/library/en-us/dllproc/synchro_2bcj.asp ("Using Waitable Timer Objects")
0
 
LVL 1

Author Comment

by:MattC
ID: 6917760
Ah, drat as usual, excellent answer....but from completely different people.

Thanks guys.  Gimme a couple of days and I will dish out some points. :-)

MattC
0
 
LVL 1

Author Comment

by:MattC
ID: 6917805
one last thing :-)

below is the Run() method.
I have put '*****************' where i think my code should go, is this right???

void CServiceModule::Run()
{
    _Module.dwThreadID = GetCurrentThreadId();

    HRESULT hr = CoInitialize(NULL);
//  If you are running on NT 4.0 or higher you can use the following call
//  instead to make the EXE free threaded.
//  This means that calls come in on a random RPC thread
//  HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    _ASSERTE(SUCCEEDED(hr));

    // This provides a NULL DACL which will allow access to everyone.
    CSecurityDescriptor sd;
    sd.InitializeFromThreadToken();
    hr = CoInitializeSecurity(sd, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    _ASSERTE(SUCCEEDED(hr));

    hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
    _ASSERTE(SUCCEEDED(hr));

    LogEvent(_T("Service started"));
    if (m_bService)
        SetServiceStatus(SERVICE_RUNNING);

    MSG msg;
    while (GetMessage(&msg, 0, 0, 0))
        DispatchMessage(&msg);

************************************** //<-- My Code here

    _Module.RevokeClassObjects();

    CoUninitialize();
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 6917810
Well, that depends on what your code is like :o)
0
 
LVL 1

Author Comment

by:MattC
ID: 6917824
:-)

see cookre's response at the top, I was gonna do something like that.
Matt
0
 
LVL 86

Expert Comment

by:jkr
ID: 6917874
>>I was gonna do something like that

Uh, so your service has a UI?
0
 
LVL 1

Author Comment

by:MattC
ID: 6917905
no, but the hWnd argument can be NULL.
0
 
LVL 86

Expert Comment

by:jkr
ID: 6917929
Yes, but the docs to 'SetTimer()' state:

"Remarks
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER."

If you don't have any UI, there will be no msg processing/dispatching...
0
 
LVL 1

Author Comment

by:MattC
ID: 6917945
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);

i thought that's what this section did?
0
 
LVL 86

Expert Comment

by:jkr
ID: 6918007
Ooops :o)
0
 
LVL 1

Author Comment

by:MattC
ID: 6918028
phew, i thought i was gonna have to rewrite a whole load of documentation there :0)
0
 
LVL 22

Expert Comment

by:cookre
ID: 6918126
Documentation?
You mean there's more to this job than coding?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6919281
>>******************************* //<-- My Code here

I think you would want to start the timer above there, then handle it in the TimerProc, outside of the loop.

-- Dan

0
 
LVL 11

Expert Comment

by:griessh
ID: 6957183
Dear MattC

I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. You can always request to keep this question open. But remember, experts can only help you if you provide feedback to their questions.
Unless there is objection or further activity,  I will suggest to split between

     "jkr, DanRollins, cookre"

comment(s) as an answer.

If you think your question was not answered at all, you can post a request in Community support (please include this link) to refund your points. The link to the Community Support area is: http://www.experts-exchange.com/commspt/

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
C++ assignment question 7 236
PDF library for Delphi 2 128
Websocket through haproxy reused connection causes "Not a valid frame" error. 4 106
Safe conversion? 4 72
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question