|
I would suggest reworking the directory watching code to use an overlapped scheme. Then youc na wait on 2 events - one for the overlapped IO to be ready, and another signaled by your program to exit the thread.
If your overlapped event is set, then get the overlapped result and process the data.
If the thread exit event is set, then cancel the overlapped request and leave your thread normally.
|
|
|
|
|
I've now created my thread suspended, then start it with a call to m_pThread->ResumeThread() . Then when the user clicks 'Cancel' I call SuspendThread() and then delete() on the CWinThread object. It works (meaning that files no longer show up), and I don't get any type of errors in my debug window when I terminate the app. So is this okay?
[insert witty comment here]
bdiamond
|
|
|
|
|
It is not ideal, but it is probably okay because windows is cleaning up your program's leaked handles and other memory leaks.
You might want to watch task manager and make sure you are not leaking some global GDI or other kernel objects.
Do this oepration on your program about 100 times and watch the handles available in task manager un der the 'performance' tab. The number of handles should not constantly increase, otherwise, your program is leaking a global handle in the kernel space that will eventually lead to windows shutting down.
The BEST thing is to always exit cleanly, and this recent solution of yours is not clean, unless you are able to successfully close the directory watch handles, even though your thread might be in the middle of waiting. Just because it is suspended, does not mean it was not in the middle of waiting.
|
|
|
|
|
I tried what you said, using my 'Start' and 'Stop'(cancel) buttons. Watching Task Manager, the number of handles is steadily increasing, as well as the number of threads. I don't think this will be a very big deal for my app because I have an option that will allow the app to start the thread automatically in OnInitDialog(). The app will only ever be watching one folder and we will probably put it in the StartUp folder so that everytime the server restarts, the app will start up also.
However, I would still like to do it a better way. I kinda looked at your first response, and I'm sorta clueless as to what you're talking about (I still consider myself a C++ beginner). But I DO know that putting a band-aid on a gunshot wound will lead to bigger problems. So if you have the time to elaborate further on your earlier comment, I'd appreciate it. The first way I had it was that the user had to actually close the app for it to stop watching the folder...I'm wondering if I should've just left it like that?
Thanks for your help!!
[insert witty comment here]
bdiamond
|
|
|
|
|
I apologize for not being clear
Watch the task manager handle count AFTER your program has closed.
I expected that you would see the count going up steadily while starting and stopping your thread, since you are killing a thread in progress.
This is what I would check, given the way it works now:
1. Start task amanger and write down the number of handles in use.
2. Start your progrma and start and stop your thread several times. You already indicated the handle count increases.
3. Close the program, and wait a moment, and then see if the handle count has returned to nearly the original number.
4. Do steps 1 - 3 about 20 times. IF the handle count returns and stays at about the original number, before starting any tests, then you are problably not in danger of stopping Windows because of handle leaks.
I will take it into consideration to post some aritcle in the future for a 'thread safe file change watcher'
|
|
|
|
|
yes, it returns to roughly the same number, give or take a few. So I guess it's cool. thanks!!!
[insert witty comment here]
bdiamond
|
|
|
|
|
|
Hi all,
I'm having a problem with my CSplitterWnd SDI app ...
It's split into 2 frames, with a CEditView on the left side, and a CDialog panel on the right with some button controls on it. After I click a button on the right panel, then do a menu->file->print, I catch a ID_FILE_PRINT message in CMainFrame. I'd like to send this to my view.
Here's my code to do this:
<br />
MainFrm.cpp -- OnFilePrint(....)<br />
<br />
CMYEDITView *pView = (CMYEDITView *)m_wndSplitter.GetPane(0,0);<br />
pView->SendMessage(ID_FILE_PRINT_PREVIEW);<br />
The message is never received by the CEditView's message map.
My question is this: Do I need to do anything special to set focus to this view before sending the Message? or is something else wrong here?
Thanks a million,
Mike
"I bet Einstein turned himself all sorts of colors before he invented the light bulb." -- Homer J.
|
|
|
|
|
Hi
Check the view's address .if prb with address get the splitters' address using getparent frame
Hope this will help
Sujan
|
|
|
|
|
Is it possible to write a shell handler that gets called when you double click a folder and that would allow you to put your own processing in place? So you could look at the directory name, and if it (the directory name) ended in "*.app" you would execute the executable that was inside of it, as opposed to opening the directory in explorer. Is this even possible ?
Thanks
Jim
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
|
|
|
|
|
Michael Dunn has written seven articles on Shell programming. Here is a link to the first one. Hopefully one of them will steer you in the right direction.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Hi,
How can I change the menu item properties dynamically? basically, I want to have the menu caption "Running!" when a certain code in my application is running and "Stopped" when the code is in standby.
Thank you for your help
Zakaria
|
|
|
|
|
Add a handler for the update of the menu item eg:
void CDocClass::OnUpdateMenuItemName(CCmdUI* pCmdUI)
{
if (m_bRunning)
pCmdUI->SetText(_T("Running"));
else
pCmdUI->SetText(_T("Stopped"));
}
Ant.
I'm hard, yet soft. I'm coloured, yet clear. I'm fruity and sweet. I'm jelly, what am I? Muse on it further, I shall return! - David Williams (Little Britain)
|
|
|
|
|
I have a memory leak and think I have found it. So my question is whats the best way to terminate this thread.
The final tidy-up section of code is never reached.
The thread reads UDP data packets and updates a database; but on my main program exit routine should I kill this thread? As could be waiting on a read.
while(g_bUDP_Socket_Created)<br />
{<br />
int len = sizeof(RxBuffer);<br />
bytesRead = recvfrom (conn_socket, (char *)&RxBuffer, sizeof(Data), 0, (struct sockaddr *)&from, &length);<br />
if (bytesRead == SOCKET_ERROR) <br />
{<br />
g_sFormatting.Format("recvfrom() failed: %d\n",WSAGetLastError());<br />
AfxMessageBox(g_sFormatting);<br />
WSACleanup();<br />
return -1;<br />
}<br />
::EnterCriticalSection(&g_csRxLock);
memcpy(&g_RxData, &RxBuffer, sizeof(Data));<br />
UpdateDataBase();<br />
::LeaveCriticalSection(&g_csRxLock);
g_nUDPCounter++;<br />
}<br />
closesocket(conn_socket);<br />
WSACleanup();<br />
return 0;
|
|
|
|
|
Seems to me you should be using an asynchronous 'unblocked' socket. Your thread should wait on an exit event and a socket event (2 events) with WaitForMultipleObejct, and only issue the socket read if socket data is ready. Otherwisee you WILL just sit there until data arrives.
See WSAEventSelect:
"As in the case of the select and WSAAsyncSelect functions, WSAEventSelect will frequently be used to determine when a data transfer operation (send or recv) can be issued with the expectation of immediate success. Nevertheless, a robust application must be prepared for the possibility that the event object is set and it issues a Windows Sockets call that returns WSAEWOULDBLOCK immediately. For example, the following sequence of operations is possible:"
Then, your application main thread can set the event for the thread to exit, and it should not be otherwise 'blocked' waiting for data reception on the socket.
|
|
|
|
|
Thanks for your post.
My application is already using events and will use more in the future. I am lead to think that you have a total of 32 events.
So do not want to use 2 events for this UDP activity.
Are they a crude way of ending this thread when the application ends? I will sort it out later if they are any events spare.
I do not have a handle for this thread, created via the call:-
m_UDPReceiverThread = ::AfxBeginThread(ExampleDlg::UDPReceiverThread, NULL);
|
|
|
|
|
1. You can have more than 32 events in your progrma, I just don't think you can WAIT for more than 32 in any particular call to WaitForMultipleObjects.
2. The receiving thread should wait on an event from the sockets AND an event that the main applciation thread would set when it is time to exit. If the soket event is set, then read data, if the exit event is set, then leave your thread function by returning or exiiting out of bottom of function. That is the preferred mechanism for ending the thread, not terminating it.
There is another message in this forum a little older than yours asking how to end the thread safely, please read it. I was not trying to give guidance on existing the thread so much as how to avoid the blocking socket call.
|
|
|
|
|
Hi,
I'm trying to create a little program, wich basicaly reads a file. I already have written some code in the serializing-fuction, wich reads the data. I now would like to add a progress bar and some info-text in my window (CFormView). I don't know how to get data from the doc class to the view class. Has it something to do with messages? I'm new at all of this stuff, so its very confusing...
Thank's in advance!
|
|
|
|
|
You can simply use CDocument's GetFirstViewPosition() and GetNextView() to access the desired view.
An alternative for frame windos is calling AfxGetMainWnd()->GetActiveView() , which gives you access to the current view.
We are men. We are different. We have only one word for soap. We do not own candles. We have never seen anything of any value in a craft shop. We do not own magazines full of photographs of celebrities with their clothes on. - Steve
|
|
|
|
|
Plons wrote:
I don't know how to get data from the doc class to the view class.
After the document has successfully loaded the file, simply call UpdateAllViews() to notify the view that it needs to display new information. In the view's OnUpdate() method, it will ask the document (usually via GetDocument() and one other method) for the data to be displayed.
Check out the Scribble tutorial on MSDN. It goes over serialization, and doc/view in great detail.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Hello Friends,
How can we retrieve an Handle of a View. I am using Splitter Window where my window is splitted into 5 parts. and I want to retrieve an handle for any of the view which ever I need. Please help me
Thank you,
Neelesh Jain.
|
|
|
|
|
I'm assuming you've made five calls to CreateView() . To access one of the views, just call GetPane() .
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Hi Jain
Sorry for the delay
Here i do consider that i am having two panes ie two views, first the CCallManagerView(0,0) and the other CUserView(1,0). So when i do need to set some value to the CCallManagerView's control from CUserView, i'll be using the following code
void CUserView::SetValue2Manager(void)
{
CMainFrame *pMainFrame = (CMainFrame *) GetParentFrame();
CCallManagerView *pView = (CCallManagerView *)pMainFrame->m_wndSplitter.GetPane(0,0);
if (pView)
{
pView->myEdit.SetWindowText("Hai From Call Manager");
}
}
Hope this may help you. If you want the CUserView then use GetPane(1,0)
Sujan
|
|
|
|
|
I need to print out some image that I have in my MFC program. I can print text byt NOT images is there anyone that now's how do make that happend?.
|
|
|
|
|