Click here to Skip to main content
15,890,512 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello! I am having a little trouble with a threading Exception. I have a program that listens opens files through command line. If another instance is open, it will use this[^] method of Piping. However, I think that it may be causing the "Cannot be called through a thread that did not create it" exception.

VB
Public WithEvents PServer As New wyDay.Controls.PipeServer

'Form Load Event Handler
PServer.Start("\\.\pipe\MainNotesPipe")

'PServer Message Received Handler
Private Sub PServer_MessageReceived(ByVal message() As Byte) Handles PServer.MessageReceived
    Dim FinalMessage As String = ""
    For Each thing As Byte In message
        FinalMessage = FinalMessage & Strings.Chr(thing)
    Next
    'Debug.Print(FinalMessage)
    Common.ProcessCommandLines({FinalMessage})
End Sub


common.ProcessCommandLines is a verification process that goes move on toward a Load process. Another thing that I haven't been able to figure out is, when it loads, the loaded form flickers a couple of times and then disappears (the issues might be related). Anyhow, The load process adds the form to an Array. The problem occurs when I call my bring-to-front function which goes through the array and tells each form to come to the front. It works properly except when I have a loaded form that went through the above process.

If anyone knows how I can fix this, please let me know. Please let me know if anymore info is needed as well.

Thanks!
Ethan
Posted

The wyday blog says that using sendmessage/getmessage blocks the apps while the message is being processed. That's simply not true, sendmessage does - postmessage does not.

He goes on to state that sendmessage/postmessage only allows intger values, that's true to some extent, but that integer value can be a pointer to an object, thus allowing the passing of complex types.

Third, IPC is completely unnecessary if you handle threading issues correctly. For .Net, you cannot update the UI from a thread unless you do it in a very specific way. You should probably google "vb.net update UI from thread", and that should answer all of your questions.
 
Share this answer
 
v2
Comments
Espen Harlinn 12-Jan-11 17:45pm    
5+ and goodnight :)
Yes, some .NET library methods refuse to be called from a thread other then the thread where the object was constructed.

For more detail, you need to spot this exception exactly and provide a dump of this exception (better with full exception step and all inner exceptions, recursively). At least, it needs the line where exception was originally thrown.

Assuming you're sure about exception and its cause, I think there are only to methods to resolve the problem:

1) Re-factor the code to have the "offender" object constructed and used in the same thread;

2) Develop a mechanism for inter-thread dispatching of calls. See below.

Such mechanisms already exist for System.Windows.Forms and WPF UI threads (see Dispatcher). I'm not explaining this further, because you're developing some Server (ask me if you need to know more). To close up this sub-topic, it's good to know that invocation through Dispatcher can be formally done anywhere, but the result is trivial (equivalent to normal call) if the thread is not .NET UI. As this is irrelevant to server development, I can provide further explanation later.

For a general-case thread, such as your server's thread, the dispatching mechanism is only specific to the thread that is supposed to make a real code. The thread doing invocation can be anything. So the thread with dispatching mechanism should provide a queue of delegates of some delegate types and retrieve data from the queue in a cycle. To cause the thread sleeping when the queue is empty System.Threading.EventHandle with manual triggering can be used, but that will block the thread, so other activities cannot be carried out in parallel (make a separate thread). The thread which invokes the action should simply provide and instance of the delegate (anonymous methods are highy welcome) to call some method which place a delegate element in the queue; this call is non-blocking.

I could provide additional assistance, only if you convince me to do so -- this is relatively easy but need a bit of working time. Most likely, first method (re-factorization) is the only reasonable for your server.
 
Share this answer
 
v2
Comments
Dalek Dave 12-Jan-11 15:25pm    
Good Answer.
Sergey Alexandrovich Kryukov 12-Jan-11 15:33pm    
Dalek, thank you, but if that was your vote, I suspect you voted even before I complete (there was an incomplete version 1) -- is that true? -- just curious...
Espen Harlinn 12-Jan-11 17:46pm    
5+ thorough answer, and goodnight :)
Sergey Alexandrovich Kryukov 12-Jan-11 18:25pm    
Thank you very much, good night and hear from you later.
I just received another "interesting" votes from some quite aggressive ignorant people, got a feeling to to speak up...

(Matchlighter, don't think: it has nothing to do with you, sorry for possible confusion. Your question is quite reasonable -- I'll vote my 5. Please let me know if you have further questions.)
Matchlighter 13-Jan-11 0:57am    
Ok, thanks I will try that. All My stuff should be in the same thread but wyDay's Server file Imports Threading, so it may create a new thread. I will have to look into that. Thanks!
Matchlighter, I remembered you were not very happy with the prospect of re-factorization of threading (to make sure you create and use some object in the same thread) and expressed interest in inter-thread invocation.

As other Inquirers asked more question which required me to advise very similar recipes, I'm putting some basic techniques in the form of small articles in Tips/Trick. Here my recent tip which describes inter-thread invocation (especially last usage sample):

Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

Well, I'm sorry this is just C# and not VB.NET. If you're interested, you don't have to know C# detail; you could just created a C# library project, add classes there (generic) and use from VB.NET. Please post a question (as a comment to my answer) if you have questions.

Good luck,
—SA
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900