|
Hi again,
I'm adding a standard text of mine about cross-thread access to GUI Controls, since you will probably need such info anyway:
Controls are not thread-safe, hence they should be touched (that is: their methods or properties called) only by the thread that created them, which normally is the main thread (aka GUI thread). Creating some controls on a different thread is unlikely to be successful, since all Controls get linked somehow: they reside on Forms, Forms are related to each other (by Parent, by Z-Order, etc), so normally all are created on a single thread.
If you violate the “don’t touch Controls from another thread” rule and are running .NET version 2.0 or above you will get an InvalidOperationException (“Cross-thread operation not valid”), which should be remedied by changing the code.
Do not set Control.CheckForIllegalCrossThreadCalls false, since that does hide the exception but does not cure the fundamental flaw in your code, so it just postpones the moment of failure, which typically will show as a non-responsive and possibly badly painted GUI.
Here are some ways to get another thread:
- explicitly launching a Thread instance
- explicitly delegating some work to a ThreadPool thread
- using a BackgroundWorker; a BGW is a separate thread with the advantage that two of its events (ProgressChanged and RunWorkerCompleted) execute on the GUI thread; however the bulk of the work normally is handled in the DoWork handler which runs on a distinct thread.
- using timers other than System.Windows.Forms.Timer; the Forms timer ticks on the GUI thread, all other use different threads to handle the periodic event;
- using asynchronous input/output, such as the DataReceived event of the SerialPort class
Any of these touching a single method or property of a Control is sufficient to create havoc; there are 5 exceptions:
- the InvokeRequired property
- the Invoke, BeginInvoke, EndInvoke and CreateGraphics methods (the latter only if the handle for the control has already been created).
If there is a need to touch the Control from another thread, one must use an Invoke pattern, which basically looks like this (using C# code, same can be done in VB.NET):
public void SetText(string text) {
if (myControl.InvokeRequired) {
myControl.Invoke(new Action< string >(SetText),
new object[] {text});
} else {
myControl.Text=text;
}
}
PS: if you follow my earlier advice you should not need Application.DoEvents() at all.
|
|
|
|
|
Hi,
Is there an event whether the mouse is over the form or not?
The normal mouseleave or mouseenter isn't exactly enough
if there are many controls on the form it is horrible...
|
|
|
|
|
architecton wrote: Is there an event whether the mouse is over the form or not?
Yup: Control .<a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousemove.aspx">MouseMove</a>[<a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousemove.aspx" target="_blank" title="New Window">^</a>] .
Good luck
I are troll
|
|
|
|
|
You are right but then i have to write this for each visible control on my form and this is not good because i only need one event and not x.
Example: Action mouse over form
Action mouse not over form
and not
Action mouse over control x
and Action mose over control y
...
Is there a better method?
It's difficult i know but i tried it and tried it
|
|
|
|
|
architecton wrote: You are right but then i have to write this for each visible control on my form and this is not good because i only need one event and not x.
You could opt to let all those controls MouseMove events point to the same eventhandler. E.g.,when you put two buttons on the screen, they can share their OnClick handler. Same can be done with the MouseMove event.
I are troll
|
|
|
|
|
Eddy Vluggen,
Mycroft Holmes,
Do you mean something like this?
Public sub Test () handles button1.mouseclick , button2.mouseclick
end sub
if yes, this is my problem and i try to avoid this
if no, could you write a short example like ton the top, please?
|
|
|
|
|
architecton wrote: if yes, this is my problem and i try to avoid this
Well, yes. Why are you avoiding it? Looks like a dandy way of sharing the same code for different controls
Although I was more considering something like this, which in the end, does the same;
Private Sub ctrl_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs)
' Do your thing here
End Sub ..and in the forms constructor, you could hook these up with AddHandler ;
AddHandler Panel1.MouseMove, AddressOf ctrl_MouseMove
AddHandler Panel2.MouseMove, AddressOf ctrl_MouseMove
AddHandler Label5.MouseMove, AddressOf ctrl_MouseMove
[...].
I are troll
|
|
|
|
|
I try to avoid this because then the mouse enters the form the backgroundimage (for example) changes and then the mouse leaves the form it also changes
BUT: the backgroundimage changes every time the mouse enters the form or a control or and the backgroundimage changes then the mouse is leaving one control and changes again then entering the next control...
this is my problem
and i cannot use the event somewhere else.
i need an event whether the mouse is over the form or not and not over an control
|
|
|
|
|
You can find out whether the Form or one of the controls fired the event by examining the sender parameter. You can differentiate your actions based on that information, for example;
Private Sub ctrl_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs)
If sender Is Form1 Then
' Do your thing here
Else If sender is control Then
' some other actions
EndIf
End Sub Enjoy
I are troll
|
|
|
|
|
So taking Eddies idea you should do the following.
Create your generic event
loop through each control on the form and add the event to each.
Note that the event footprint must be valid for each control. You may need to test to see if the control accepts a mouseover event
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Here is an alternative solution that lets you put as many controls on your form as you like, without having to write extra lines of code for each:
All you need to do is add a timer and determine an interval to your taste (I just successfully tested with 10 milliseconds, and I have a 5 year old PC).
Public Class Form1
Dim ne As New Point(Me.Top, Me.Left)
Dim sw As New Point(Me.Top + Me.Height, Me.Left + Me.Width)
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Timer1.Start()
End Sub
Private Sub Form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
ne = New Point(Me.Top, Me.Left)
sw = New Point(Me.Top + Me.Height, Me.Left + Me.Width)
End Sub
Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
ne = New Point(Me.Top, Me.Left)
sw = New Point(Me.Top + Me.Height, Me.Left + Me.Width)
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
With Control.MousePosition
If .X > ne.X And .Y > ne.Y And .X < sw.X And .Y < sw.Y Then
TextBox1.BackColor = Color.Azure
Else
TextBox1.BackColor = Color.White
End If
End With
End Sub
End Class
Now I just whipped this up quickly, and I must admit that after moving and/or resizing the form this does not work smoothly yet, with this code. If you want to use this idea, you may have to work on that.
My advice is free, and you may get what you paid for.
modified on Tuesday, April 21, 2009 2:04 AM
|
|
|
|
|
Thankyou for your code, Johan Hakkesteegt
since now i have some problemes with it but this is not your fault
Thanky very much, all of you!!!!!
|
|
|
|
|
hi all
i have one problem ,when entered salary amount in textbox its only display 2000rs , here i want 2000.00 format .
Pls give me code how can i write that format (2000.00)
|
|
|
|
|
|
Dim mySalary As Double = 2000
txtSalary.Text = mySalary.ToString("$0.00")
...
or
Public Sub txtSalary_Validate(...)...
If IsNumeric(txtSalary.Text) = True Then
txtSalary.Text = CDbl(txtSalary.Text).ToString("$0.00")
End If
End Sub
I don't speak Idiot - please talk slowly and clearly
I don't know what all the fuss is about with America getting it's first black president. Zimbabwe's had one for years and he's sh*t. - Percy Drake , Shrewsbury
Driven to the arms of Heineken by the wife
|
|
|
|
|
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
TextBox1.Text = CDbl(TextBox1.Text).ToString("F")
End Sub
but make sure that only numeric values are entered.
My advice is free, and you may get what you paid for.
|
|
|
|
|
Hi All,
I am getting an error when am sending a data through memorystream in VS 2008.
'There was an error generating the XML document. ---> System.InvalidOperationException: Timeouts are not supported on this stream.
at System.IO.Stream.get_ReadTimeout()'.
I didn't understand that why a simlpe memorystream requires Timeouts.
Any help/suggestions would be highly appreciated.
Thanks & Regards
Viram Pandey
|
|
|
|
|
Without seeing the code you wrote to create the memory stream and the code where this error occured, it's pretty much impossible to tell you what's going on.
|
|
|
|
|
Hi Dave,
Thanks for your response.
Actually i am using a memorystream which contains a data through dataset.
But the issue is a different one, whenever i create a new object of IO.memorystream, in its 'ReadTimeOut' and 'WriteTimeOut' properties, it is showing the message that 'Timeouts are not supported in this stream'. I am nowhere using the timeouts for the memorystream. When my code progresses, the same error is thrown back.
I am attaching a code snippet for your reference. I am using VS 2008 and a WCF service is interacting with a web service.
''''''
Public Shared Function GetCompressedData(ByVal coployeeDataSet As DataSet) As IO.MemoryStream
Dim compressedData As New MemoryStream()
Dim coployeeFormatter As New BinaryFormatter
Dim objCompression As New Compression.GZipStream(compressedData, Compression.CompressionMode.Compress, False)
coployeeDataSet.RemotingFormat = SerializationFormat.Binary
coployeeFormatter.Serialize(objCompression, coployeeDataSet)
Return compressedData
End Function
'''''''
Thanks
|
|
|
|
|
Hi,
i have a certifiacte in webserver and i want all of my clients to view the certificate when they try to access the html page in server...(installing certificate is upto client)just i need to show the certificate to proceed further....So please let me now is there any tag or something like that to add in my html page .....to display certificate when clients try to access the html ....
Please let me know....
|
|
|
|
|
You really need to abandon this idea until you get a grasp of the basics of a web server and security. Seriously, pick up a book on Internet Information Server and work through it before you try to do this again. What you're getting into can't be described and "step-by-step" explained in a forum post, to the point that you need to understand it to support it.
There is a VERY good reason why the machines resources are off-limits to code running in web browsers. If you have heard of a "virus", or a "trojan horse", then you really need to stop what you're doing and and learn about why things work in a web browser the way they do.
|
|
|
|
|
Hi,
I am Working on the VB.Net to perform a Multithreading to correct the invalid email addresses in Database. The problem is that I have 22,00,00,000 email addresses. So I want, Multiple threads do work on this process .
I am Little bit confusion about how to create more threads and all the threads can work togather but not access the same IDs of Email Address from table .
For doing this I ahve created a list box , in which I devided the IDs of email Addressses into many list items . I want that first thread do work on first list item , Second created thread do work on second list item and so on.
But the problem is that when i created multithreading some list of item is missing and the threads cannot do work on some list of items.
With Regards,
|
|
|
|
|
Multithreading will not actually make your application perform multiple updates at the same time. Instead it will just have the one thread perform one, then the second one, then the third one, then the first one again, etc.
It will be much faster doing the whole thing with SQL. You wouldn't even need an application at all, just a stored procedure or an SQL job.
My advice is free, and you may get what you paid for.
|
|
|
|
|
I think you do not understand the problems exactly.
I ahve lots of email addresses in my database .
and a single query take a lot of time of its execution.
so in this satuation it will happns that may the whole prrocess take
few days in completing which is not useful for me.
thnks!
with best wishes!!!!!
|
|
|
|
|
I do understand what you mean. What I am trying to say, is that any application using threading, you write, will always use the capacity of your PC or server in a less efficient way than the database server program would.
Again, multithreading in principle does not make the computer perform multiple actions at the same time. It only makes the computer perform these actions in rapid succession, so it looks like it is doing things at the same time.
Your database server program however can and will (usually) readily use multicore CPU's or servers with multiple CPU's. So it will actually make your PC or server perform multiple actions at the same time.
If you need to sort through that much data, you are going to have to be prepared for a lengthy process, although I seriously doubt it would take days. Hours maybe.
So it would be best if you create one additional field in your table, where you can flag each email address when it has been checked.
That way you can write your SQL so that it only checks unflagged addresses, and your sql job or stored procedure will only have to run for a long time the first time.
My advice is free, and you may get what you paid for.
|
|
|
|
|