-
Feb 11th, 2018, 03:39 PM
#1
Thread Starter
Addicted Member
Displaying Data in a Separate Terminal / Form
Hi,
I have read in this forum many times that it's not a good idea to move data from one form to another. I am working on a program where I have the following code,
Code:
engineListener = Observable.Timer(TimeSpan.Zero, TimeSpan.FromMilliseconds(1)).Subscribe(Sub() ReadEngineMessages())
Private Sub ReadEngineMessages()
Dim message = strmReader.ReadLine()
If message <> String.Empty Then
txbEngine.Text = txbEngine.Text & message.ToString() & Chr(13) & Chr(10)
RaiseEvent EngineMessage(message)
End If
End Sub
I'm displaying the output of this "listener" in a TextBox in the same form for testing purposes. I need to display this data in a separate form/terminal or whatever works, so I can maximize it and display it in a separate monitor. Any ideas?
Thanks,
Robert
-
Feb 11th, 2018, 04:59 PM
#2
Re: Displaying Data in a Separate Terminal / Form
Holy smokes. Another person uses the reactive framework on this forum. Now I have to answer.
Your biggest problem right now's going to be I'd expect Observable.Timer() to emit its messages on a worker thread, so your code's starting out dangerous. There's a way to tell Rx to do that work for you, but it involves importing System.Reactive.WindowsForms and I'm not near a Windows machine so I can't double-check everything. You'd look for a call chain that ends up something like this:
Code:
Observable.Timer(...)
.SubscribeOn(WindowsFormsScheduler.Instance)
.Subscribe(Sub() ReadEngineMessages())
I'll write code assuing you don't do that, just in case.
Now, let's really start. Wherever you heard this, I think you misinterpreted:
I have read in this forum many times that it's not a good idea to move data from one form to another.
The only thing "bad" about moving data between forms is you need to be aware of if you want both forms to be able to edit the data, and if so you need to make sure both are aware it happens. That's complexity, and in the context of TableAdapters and DataSets like so many of our forum threads it can trip a lot of people up.
In your case, you just want to send some text to another form as a debugging aid. This is actually really useful. You just need to keep track of the Debug form and add stuff to it when needed. If you use methods and properties instead of directly accessing the controls, you can make it even easier.
Here's a quick example of a form that references a different form. ExampleForm is just a plain old form with a button on it. DebugForm is a form with a TextBox on it that's had its Multiline property set to True. Try this out and see if it gives you ideas.
Code:
Public Class ExampleForm
Private _debugForm As New DebugForm()
Protected Overrides Sub OnShown()
_debugForm.Show()
End Sub
Private Sub Button1_Click(...) Handles Button1.Click
_debugForm.AddMessage("Hello!")
End Sub
End Class
That just creates a new DebugForm and shows it when the ExampleForm loads. When you're done testing, you can delete the bits that work with the DebugForm. Here's the DebugForm:
Code:
Public Class DebugForm
Public Sub AddMessage(ByVal message As String)
txtMessages.AppendText(message & Environment.NewLine)
End Sub
End Class
Now, I warned you about threading issues here, so before you go using this DebugForm with your Reactive code, it'd be safer to:
Code:
Public Class DebugForm
Public Sub AddMessage(ByVal message As String)
txtMessages.Invoke(Sub()
txtMessages.AppendText(message & Environment.NewLine)
End Sub)
End Sub
End Class
That'll force the update to always happen from the UI thread and avoid nasty problems.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Feb 11th, 2018, 07:18 PM
#3
Thread Starter
Addicted Member
Re: Displaying Data in a Separate Terminal / Form
Smitten, thanks a lot for your help. When it comes to the observable.timer() part, that's way above my head. Maybe, I should open a new thread asking for help on this issue. Can you please guide me in the right direction about this timer() issue? Do you have sample codes?
About the data been displayed in multiple forms, thank you for clarifying this for me. I have a better understanding now about this issue. Thanks.
-
Feb 11th, 2018, 10:53 PM
#4
Re: Displaying Data in a Separate Terminal / Form
You posted the Observable.Timer() code in your own example. Surely you understand your own code?
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Feb 20th, 2018, 01:57 AM
#5
Thread Starter
Addicted Member
Re: Displaying Data in a Separate Terminal / Form
Originally Posted by Sitten Spynne
You posted the Observable.Timer() code in your own example. Surely you understand your own code?
Thanks. The DebugForm worked very well.
I've got the code for the Observable.Timer(...) from CodeProject. I understand how the basics of this code works, but when you started talking about "threading issues" you threw me off. The way I look at the Observable.Timer(...) code is like a regular timer that executes every 1 mS in my case. Any clarifying comments are welcome.
Thanks, Robert
-
Feb 21st, 2018, 12:36 AM
#6
Thread Starter
Addicted Member
Re: Displaying Data in a Separate Terminal / Form
Hi, can somebody explain what Sitten meant by "threading issues"? Does that have anything to do with the CPU usage?
-
Feb 21st, 2018, 12:52 AM
#7
Re: Displaying Data in a Separate Terminal / Form
Originally Posted by VB-MCU-User
Hi, can somebody explain what Sitten meant by "threading issues"? Does that have anything to do with the CPU usage?
He means that you cannot access a control directly from any but the UI thread, so you must marshal a method call from a secondary thread to the UI thread in order to update the UI. That's what the Invoke call is for, or you can call BeginInvoke to do it asynchronously.
To clarify, given that Invoke is called on the control too, when I say "access a control" I mean use any member that makes use of the control's handle. That handle is owned by the UI thread.
-
Feb 21st, 2018, 01:10 AM
#8
Thread Starter
Addicted Member
Re: Displaying Data in a Separate Terminal / Form
Thank you. That explanation helps.
-
Feb 21st, 2018, 09:04 AM
#9
Re: Displaying Data in a Separate Terminal / Form
"Observables" at a high level are like "Enumerables" that raise an event when an item is added. Another way to look at them is "they are like IEnumerables of events".
When you call Subscribe(), you are saying "every time something is added to this list, I want you to give it to this method so I can do something with it". This is basically saying, "I'd like to subscribe to the event." That method is called the "next" handler, there is also an "error" and "completed" handler.
By default, the "next" handler is called on a worker thread. If you don't want that to happen, then you have to call SubscribeOn() before Subscribe() so you can describe the context you'd like to use.
That's why I mentioned threading. By default, the code you wrote involves a worker thread.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|