|
I've been noticing a strange problem related to threading and debugging them in VS .Net 2003 recently and am not sure if this is a) a bug in VS b) something odd I just don't understand and/or c) the cause of a related problem I seem to be having.
The issue is this, I'm using ThreadPool.QueueUserWorkItem to create various asynchrous actions. The generally works fine. On occassion (its difficult to exactly replicate) my process suddenly starts using 100% of my machine's processor without stopping. When I pause the execution in VS and look at the threads there are two listings for some threads (e.g. thread with ID 2480 is listed twice) but they are in the same execution position and seemingly one in the same. This is quite odd to me. I've noticed it happening for some time both using ThreadPool and when I create my own threads. There is no rhyme or reason why nor logic why some are double entered and some are not from a code standpoint. I tried to debug the creation some time back but could not get it to stop from listing twice.
So my question is as above, is this a VS bug, some strange thing happening in my code, or some other artifact? I can't confirm but I'm suspicious this is why I'm getting runaway threads who, when I try and debug them, the debugging info is all corrupt and I can barely even step through them. Any and all suggestions are welcome. I'm a bit of a newbie with VS.
Thanks in advance,
Andy
|
|
|
|
|
Do your threads have large loops in them? eg:
1) start thread
2) enter loop until thread closes down
3) close thread
You may need Thread.Sleep(1) in the the loop, this should stop your thread eating up 100% of the processor.
Cheers, James
James Simpson
Web Developer
imebgo@hotmail.com
P S - This is what part of the alphabet would look like if Q and R were eliminated Mitch Hedberg
|
|
|
|
|
Hello, All
I'm in the process of writing a custom editcontrol GUI Widget. e.g. TextControl. I currently have a control that users can enter text and highligh text etc. I'm running into 2 problems listed below.
Problem #1
When trying to invert the color of the text when a line is selected sometimes the text drawn over the black text does not align if i only draw a subset starting in the middle.
If i select the entire line then it works perfectly.
1) It appears that when using DrawString if you draw 2 text lines for example:
First Line: Hello, This is a sample text line
offset = measureString(Hello, This is )
// -- draw x with offset on line
invert text: a sample text
this leads me to belive that char's are draw with a differnt about of leading space if draw in differnt contexts. So the width of ie and i + e is not equal.
Does anyone know another solution to this?
Problem #2
This is my first time attempting to code a editcontrol
from scratch so what is the proper tecnique for painting the control. Currently the screen us refreshing every line on each keypress. Basiclly, I'm drawing text line by line. All drawing is currently done in the Paint event. Does anyone know a better way?
Thanks,
Kevin Fowlks
Programmer Analyst
Michigan State University
Center for Remote Sensing & GIS
|
|
|
|
|
kfowlks wrote:
When trying to invert the color of the text when a line is selected sometimes the text drawn over the black text does not align if i only draw a subset starting in the middle.
If i select the entire line then it works perfectly.
Might be something to do with kerning. How big is the difference between the two positions?
kfowlks wrote:
This is my first time attempting to code a editcontrol
from scratch so what is the proper tecnique for painting the control. Currently the screen us refreshing every line on each keypress. Basiclly, I'm drawing text line by line. All drawing is currently done in the Paint event. Does anyone know a better way?
Because of word-wrapping (provided that you are doing true word-wrap), this may well be so. I would strongly advise double-buffering (and not with the built-in double-buffering either - it updates the screen after each drawing operation, rather than after all of the operations are complete).
I'm interested in your results and findings, as I'm going to be writing a text editor myself soon. If you find something of interest in the areas, or just want to discuss aspects of a textbox implementation, feel free to drop on over at the Fluid forums[^].
|
|
|
|
|
The difference between the two position is minor but it is not constent. I'm starting to think the only way to correct the problem is to draw a char at a time. I've read about other people having the same issue and that was there solution.
Currently, I've only implemented char wrapping.
If your intrested i'll let you take a peak at what i've got so far. I'll drop by the FLUID forum.
Kevin Fowlks
Programmer Analyst
Michigan State University
Center for Remote Sensing & GIS
|
|
|
|
|
In C++ we have a macro __LINE__ that can be used to report what line of source code we are on. Is there a way to do this in C#?
|
|
|
|
|
I found this:
CodeLinePragma clp = new CodeLinePragma("Service1.cp",188);
but it doesn't seem to keep up with the line number... it just reports back whatever I initialize it with.
|
|
|
|
|
That's just the CodeDom class that represents the #line preproc instruction, mostly used in debugging and error/warning reporting during compilation, if one was to strip the lines for some stupid reason.
What do you need something like this for? If it's for debugging purposes, exceptions will already contain line numbers for assemblies compiled with debugging information. When doing release builds (i.e., DEBUG is not defined), this information is stripped.
If you're doing it for some kind of logging, I don't know what to tell you. csc.exe doesn't doing anything like that based on the documentation. If using VS.NET 2003, you could have a pre-build step that runs a macro to replace some line with the line number (I would think that would be available through the scripting object model in VS.NET).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Thank you for your reply! I'm currently working on some services and I'm not seeing the line number when I catch an exception.
Maybe it's because I handled the exception - by exiting my service but this is an example of what my exception reports:
System.Data.SqlClient.SqlException: SHUTDOWN is in progress. Log off.
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream)
at System.Data.SqlClient.SqlCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(Object data, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable)
at GetAcc.GetAcc.timer1_Elapsed(Object sender, ElapsedEventArgs e)
I want the line number so I know where (which exception trap) trapped the error. In a case like the example above (depending on what step I'm in in my process) I may be able to keep my service alive until the SQL server is available again.
I have found that I can use Environment.StackTrace which gives more info... but does include the line number. So I'm adding that to my message that I log to a file.
|
|
|
|
|
If you do a debug build, you should get line numbers for your assemblies (.NET BCL assemblies obviously aren't debug assemblies). I take it you're testing this with a release build? You also have to use the same path for the PDB files (debug files) that were created when you compiled. That contains the information. If you switch to a different machine (unless you keep the path to the copied PDB files the same), you don't see this. Does that ring a bell at all?
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Oh... ok I am using debug builds... but I have not copied PDB file to the production machine. When I tested Environment.StackTrace I was on my development machine. I bet I won't get line numbers from that either on the production machine.
Thanks again!
|
|
|
|
|
Heath Stewart wrote:
What do you need something like this for? If it's for debugging purposes, exceptions will already contain line numbers for assemblies compiled with debugging information. When doing release builds (i.e., DEBUG is not defined), this information is stripped.
If one generated some code from some other source, its allways helpful to make #line references. Think lex & yacc for example
leppie::AllocCPArticle("Zee blog"); Seen on my Campus BBS: Linux is free...coz no-one wants to pay for it.
|
|
|
|
|
Heath Stewart wrote:
if one was to strip the lines for some stupid reason.
One place this is done is in ASP.NET code that's embedded in the page.
|
|
|
|
|
For repainting the nonclient area myself, I process the message WM_NCPAINT.
But the value got from wParam always is 1. Why? How can I get the nonclient area's graphics?
|
|
|
|
|
If you have a reference to the non-client area, you can use Control.CreateGraphics to return a Graphics object for any control. Remember to call Graphics.Dispose on it when you're done, though.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I know I can get the form's graphics with CreateGraphics(). Can I get the title bar's graphics? or How can I determine the title bar's retangle?
The wParam gotten from WM_NCPAINT always is 1.
|
|
|
|
|
Right, I didn't catch that before. The wParam in the WM_NCPAINT message should be 1 if the entire window frame needs repainting (covered in the docs for WM_NCPAINT). Also in that same doc is an example that you could easily use after importing a couple Win32 functions (I can't think of or find any .NET equivalents).
P/Invoke GetDCEx (optionally ReleaseDC , but Graphics.Dispose would free the handle). and pass hwnd , (HRGN)wParam , and DCX_WINDOW|DCX_INTERSECTRGN . Even though hwnd is 1, this supposedly works (at least according the docs).
I tried a quick example and got minimal success. Of course, I threw it together quickly. I also found on that Graphics.FromHwnd works when passing the Message.HWnd field from the overridden DefWndProc for my form.
Hopefully this helps somewhat. Good luck!
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Please check following codes, it dosen'g work properly, the title bar is still empty.
( the method PanitNonClientArea(Graphics, RectangleF) can work properly. )
<br />
protected override void WndProc(ref Message m)<br />
{<br />
Graphics g;<br />
RectangleF rectf;<br />
<br />
Point pt;<br />
<br />
switch (m.Msg)<br />
{<br />
case WMConsts.WM_NCPAINT :<br />
IntPtr hrgn = m.WParam;<br />
if ( hrgn != (IntPtr)1 )<br />
{<br />
Region rgn = Region.FromHrgn(hrgn);<br />
g = CreateGraphics();<br />
rectf = rgn.GetBounds(g);<br />
PaintNonClientArea(g, rectf);<br />
}<br />
else<br />
{<br />
g = CreateGraphics();<br />
rectf = new RectangleF(0,-23, Width, 23);<br />
PaintNonClientArea(g, rectf);<br />
g.Dispose();<br />
}<br />
<br />
break;<br />
<br />
default :<br />
base.WndProc (ref m);<br />
break;<br />
}<br />
}<br />
|
|
|
|
|
As a quick note, and this may be trivial, but all implementations I've seen (including in Win32) always call the "base" WndProc or DefWndProc . You're only doing it if the message isn't WM_NCPAINT .
Also, the docs for WM_NCPAINT say that it calls the DefWindowProc , which is DefWndProc in the Control class. Did you try putting a breakpoint in your code to see if it's even getting there? If not, you might try moving this to an override of DefWndProc instead of WndProc . I don't know, maybe both callbacks get it.
As I said in my previous post, I had some success. I forgot to mention that I was using Graphics.FromHwnd instead of CreateGraphics . This seemed to work in most cases. I was able to ruin the nonclient area, but could never paint in it. Apparently, I was able to create a Graphics object successfully, but I would always get an exception when creating a Region from the wParam , which would explain why I couldn't paint anything (I couldn't get the bounds in which to paint).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I found that there is not difference between WndProc and DefWndProc .
Sometimes the WM_NCPAINT 's wParam is 1. In this case, it will not be successful to create a Region .
I found the graphics retrived not the same between
<br />
IntPtr hdc = GetWindowDC(m.HWnd)<br />
Graphics g = Graphics.FromHDC(hdc)<br />
and
<br />
Graphics g = Graphics.FromHWnd(hdc)<br />
|
|
|
|
|
I found the graphics using Control.CreateGraphics only contains the client area, not contains the title bar.
|
|
|
|
|
I can capture the screen using C#,but don't include the cursor.
How can I capture the screen with cursor?
thanks.
|
|
|
|
|
There are actually several articles on how to do this with C# here on CP (just do a search). As far as the mouse cursor, most code I've seen (even in VC++) hide the cursor, do a BitBlt and show the cursor again. Don't hide the cursor for it to show up in the captured image.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
How to implement the doubleclick Event on a Windows.Forms.Button-Control although a single click event is already implemented? How to make it work correctly? How to decide between a single and a double click to call certain code?
SetStyle-event only does not take any effect.
Mr. Labenche
|
|
|
|
|
Even in Win32 code when the two click types are handled, you need to use a timer of sorts. The Click event should start it and the DoubleClick event should stop it and continue handling the event. If the timer goes off, you handle the single-click event (in the timer's Elapsed event handler). If you look at the SDK docs for the Control.DoubleClick event, this behavior is actually discussed. The solution is common.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|