Not Understanding Delegates (User Error)
-
As the subject states I am having some trouble with implementing a delegate to solve this issue that I am having. The error that I am receiving is that cross-thread operation is not valid. I have windows form that we will call Form1 for example that has many buttons. For one those buttons opens up another form that we will call for this example Form2 that will display some data. Form2 has a COM obj that is similar to a datagridview, but it displays the data which is similar to a pdf viewer that can allowing zooming and formatting. Before I start posting where my problem is in code I did some searches and everyone suggests to use Delegates to prevent the cross-threading problem. I am quite new to delegates so I have been reading the MSDN Documentation[^] about delegates, but I am still not understanding it quite well. Also, I have read this great article A Beginner's Guide to Delegates[^] about 3 times. I understand it's a introduction article. Here is snippet of code that is causing me problems while I am using delegates (incorrectly???) Note: This snippet of code is from Form1
' Create a Delegate to prevent cross-thread exception from occuring
Public Delegate Sub StoreDetailedOutputID(ByVal strID As String)
Private strKey1 As StringPrivate Sub AnalysisResultsEngineName(ByVal strEngineName As String)
frmAnalysis_Results_Form.Set_Engine_Name(strEngineName) 'THIS IS WHERE THE CROSS-THREAD ERROR OCCURS
End SubPrivate Sub cmdSpreadSheetOutput_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdSpreadSheetOutput.Click
strKey1 = "Please work!"
' DELEGATE
Dim dEngineName As StoreDetailedOutputID
dEngineName = AddressOf AnalysisResultsEngineName
dEngineName.Invoke(strKey1)'frmAnalysis_Results_Form.ShowDialog() 'Commented Due to this line of code is never called
End SubWith that I have a few additional questions so that I may understand what delegates are all about. -Where should the delegate be created within my program? Form1? Form2? -Should the Delegates be created on both forms? -Sho
-
As the subject states I am having some trouble with implementing a delegate to solve this issue that I am having. The error that I am receiving is that cross-thread operation is not valid. I have windows form that we will call Form1 for example that has many buttons. For one those buttons opens up another form that we will call for this example Form2 that will display some data. Form2 has a COM obj that is similar to a datagridview, but it displays the data which is similar to a pdf viewer that can allowing zooming and formatting. Before I start posting where my problem is in code I did some searches and everyone suggests to use Delegates to prevent the cross-threading problem. I am quite new to delegates so I have been reading the MSDN Documentation[^] about delegates, but I am still not understanding it quite well. Also, I have read this great article A Beginner's Guide to Delegates[^] about 3 times. I understand it's a introduction article. Here is snippet of code that is causing me problems while I am using delegates (incorrectly???) Note: This snippet of code is from Form1
' Create a Delegate to prevent cross-thread exception from occuring
Public Delegate Sub StoreDetailedOutputID(ByVal strID As String)
Private strKey1 As StringPrivate Sub AnalysisResultsEngineName(ByVal strEngineName As String)
frmAnalysis_Results_Form.Set_Engine_Name(strEngineName) 'THIS IS WHERE THE CROSS-THREAD ERROR OCCURS
End SubPrivate Sub cmdSpreadSheetOutput_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdSpreadSheetOutput.Click
strKey1 = "Please work!"
' DELEGATE
Dim dEngineName As StoreDetailedOutputID
dEngineName = AddressOf AnalysisResultsEngineName
dEngineName.Invoke(strKey1)'frmAnalysis_Results_Form.ShowDialog() 'Commented Due to this line of code is never called
End SubWith that I have a few additional questions so that I may understand what delegates are all about. -Where should the delegate be created within my program? Form1? Form2? -Should the Delegates be created on both forms? -Sho
A
Delegate
is a method-pointer, you could look at it as an interface on a method-only-level. That means that it defines aType
, like anInteger
, but not for data, but for methods. That means you can store a reference to a method. When a single-threaded application is executed, it's the UI-thread or the main-thread that builds the controls. A thread executes the instructions in the code one after another. That's why you sometimes see a form go completely white when it is doing a lot of processing; the UI thread is too busy to do the drawing. To prevent that from happening, and have a responsive UI, we do the heavy work on a separate thread.Clark Kent123 wrote:
-Where should the delegate be created within my program? Form1? Form2?
On the place where you intend to call it, you'll need an instance. That instance could be passed using a parameter, as a
Delegate
is aType
that "acts" as a variable.Clark Kent123 wrote:
-Should the Delegates be created on both forms?
No, but the delegate is often public, so that it's
Type
can be used in other forms (from where it's called, for instance)Clark Kent123 wrote:
-Should I use BeginInvoke instead of Invoke?
Invoke
should execute it on the same thread; that Exception you mention should only occur when you useBeginInvoke
, as that creates a new thread. In that case you'll also need the Invoke-pattern[^].Clark Kent123 wrote:
-Is Delegates indeed the correct route to go? Should I use Threading?
You should be able to answer that by yourself now; threading is for heavy tasks, delegates are method-variables. Here's an example that uses both;
Imports System.Windows.Forms
Imports System.ThreadingPublic Delegate Sub MyCallbackProto(Count As Integer)
Public Class TheThreadClass: Inherits Object
Private mySomeCallbackRoutine As MyCallbackProto
Private myThread As ThreadPublic Sub New(aSomeCallback As MyCallbackProto) mySomeCallbackRoutine = aSomeCallback myThread = New Thread(AddressOf W
-
A
Delegate
is a method-pointer, you could look at it as an interface on a method-only-level. That means that it defines aType
, like anInteger
, but not for data, but for methods. That means you can store a reference to a method. When a single-threaded application is executed, it's the UI-thread or the main-thread that builds the controls. A thread executes the instructions in the code one after another. That's why you sometimes see a form go completely white when it is doing a lot of processing; the UI thread is too busy to do the drawing. To prevent that from happening, and have a responsive UI, we do the heavy work on a separate thread.Clark Kent123 wrote:
-Where should the delegate be created within my program? Form1? Form2?
On the place where you intend to call it, you'll need an instance. That instance could be passed using a parameter, as a
Delegate
is aType
that "acts" as a variable.Clark Kent123 wrote:
-Should the Delegates be created on both forms?
No, but the delegate is often public, so that it's
Type
can be used in other forms (from where it's called, for instance)Clark Kent123 wrote:
-Should I use BeginInvoke instead of Invoke?
Invoke
should execute it on the same thread; that Exception you mention should only occur when you useBeginInvoke
, as that creates a new thread. In that case you'll also need the Invoke-pattern[^].Clark Kent123 wrote:
-Is Delegates indeed the correct route to go? Should I use Threading?
You should be able to answer that by yourself now; threading is for heavy tasks, delegates are method-variables. Here's an example that uses both;
Imports System.Windows.Forms
Imports System.ThreadingPublic Delegate Sub MyCallbackProto(Count As Integer)
Public Class TheThreadClass: Inherits Object
Private mySomeCallbackRoutine As MyCallbackProto
Private myThread As ThreadPublic Sub New(aSomeCallback As MyCallbackProto) mySomeCallbackRoutine = aSomeCallback myThread = New Thread(AddressOf W
I appreciate that answer. Yeah, I do agree that by now I should be able to answer whether threading or Delegates is the way to go. I am going to stick with Delegates and take some time to digest all this information. As well as go reread all those delegate articles. I am sure later on I will look back and think of how easy it was to set this up. :) Thanks again.
-
I appreciate that answer. Yeah, I do agree that by now I should be able to answer whether threading or Delegates is the way to go. I am going to stick with Delegates and take some time to digest all this information. As well as go reread all those delegate articles. I am sure later on I will look back and think of how easy it was to set this up. :) Thanks again.
Clark Kent123 wrote:
I appreciate that answer.
..which motivates to answer questions. Thanks for the feedback :)
Clark Kent123 wrote:
I do agree that by now I should be able to answer whether threading or Delegates is the way to go.
That depends on how good my explanation was; if it isn't clear, then my explanation wasn't what it should have been. I agree that I kinda buried you under a lot of information.
Threads are for long-running, CPU intensive tasks. Delegates are variables for methods.
Depending on what you are doing to Form2 (from the point of view from Form1), you might need an event, not just a delegate. Let's try it another way;
- Are you trying to "inform" another class that something changed? (event)
- Are you trying to "execute" another method from another class? (delegate)
- Are you trying to "run" something that seems to hang your app? (threads)
Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]
-
Clark Kent123 wrote:
I appreciate that answer.
..which motivates to answer questions. Thanks for the feedback :)
Clark Kent123 wrote:
I do agree that by now I should be able to answer whether threading or Delegates is the way to go.
That depends on how good my explanation was; if it isn't clear, then my explanation wasn't what it should have been. I agree that I kinda buried you under a lot of information.
Threads are for long-running, CPU intensive tasks. Delegates are variables for methods.
Depending on what you are doing to Form2 (from the point of view from Form1), you might need an event, not just a delegate. Let's try it another way;
- Are you trying to "inform" another class that something changed? (event)
- Are you trying to "execute" another method from another class? (delegate)
- Are you trying to "run" something that seems to hang your app? (threads)
Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]
Quote:
Depending on what you are doing to Form2 (from the point of view from Form1), you might need an event, not just a delegate. Let's try it another way; Are you trying to "inform" another class that something changed? (event) Are you trying to "execute" another method from another class? (delegate) Are you trying to "run" something that seems to hang your app? (threads)
In all honesty, I am just trying to prevent the error message from popping up. So I was not paying too close attention on what Delegates were, but had the mind set of copy and paste sample code and hope the error goes away. I think the "informing" the other class that something has changed might be the what I want to do. Upon reading and reflecting (something new this time :)) on what delegates can do I think a delegate event might be beneficial in my scenario. I think. It's an experiment I want to try. I stumbled upon this MSDN VB related documentation[^] that lead me to thought of trying the delegate event. My mind set of programming has been linear that the idea of something asynchronously is foreign to me and it's taking me a while to grasp how to implement it in my app. I get the concept of what it does, but I am not yet there of saying "Oh, this would be a perfect place to make this method async with threads" or "Wait, this needs a delegate". I hope that makes sense.
-
Quote:
Depending on what you are doing to Form2 (from the point of view from Form1), you might need an event, not just a delegate. Let's try it another way; Are you trying to "inform" another class that something changed? (event) Are you trying to "execute" another method from another class? (delegate) Are you trying to "run" something that seems to hang your app? (threads)
In all honesty, I am just trying to prevent the error message from popping up. So I was not paying too close attention on what Delegates were, but had the mind set of copy and paste sample code and hope the error goes away. I think the "informing" the other class that something has changed might be the what I want to do. Upon reading and reflecting (something new this time :)) on what delegates can do I think a delegate event might be beneficial in my scenario. I think. It's an experiment I want to try. I stumbled upon this MSDN VB related documentation[^] that lead me to thought of trying the delegate event. My mind set of programming has been linear that the idea of something asynchronously is foreign to me and it's taking me a while to grasp how to implement it in my app. I get the concept of what it does, but I am not yet there of saying "Oh, this would be a perfect place to make this method async with threads" or "Wait, this needs a delegate". I hope that makes sense.
Clark Kent123 wrote:
In all honesty, I am just trying to prevent the error message from popping up. So I was not paying too close attention on what Delegates were, but had the mind set of copy and paste sample code and hope the error goes away.
I quickly dropped that method of learning, as it becomes frustrating very quickly. Incomplete samples, fishing out the unrelated parts, the "cool" feature you missed because the example used a simpeler overload..
Clark Kent123 wrote:
I think the "informing" the other class that something has changed might be the what I want to do.
Hehe, I was afraid that this would be the answer; there's a specialized form to use the delegate, called the event. If your class where to "notify" another class that it has finished loading that huge text-file, you'd typically raise an event (RaiseEvent[^]), something called "OnLoadFinished" or something like that.
Clark Kent123 wrote:
I am not yet there of saying "Oh, this would be a perfect place to make this method async with threads" or "Wait, this needs a delegate".
All too well; especially if a technique is still abstract in ones mind, often the case with design-patterns. To make it worse, there are usually multiple ways to achieve something, often with no clear "correct" way, but multiple trade-offs to go either here or there.
Clark Kent123 wrote:
My mind set of programming has been linear that the idea of something asynchronously is foreign to me and it's taking me a while to grasp how to implement it in my app.
As a quick rule-o-thumb, anything that takes more than 0.5 second to complete, should be on it's own thread. Loading large pictures, parsing text-files, loading large tables; all of those would be candidates for their own thread (ideally with a progress-indication). Learning threading, delegates and events all at once is a bit much to dive into. I suggest you pick one of the three and try to create the smallest console-app possible to see it in action. MSDN is your friend here :)
Bastard Programmer from Hell :suss: if you can't read my code, try converting it <