-
Aug 19th, 2019, 02:23 PM
#1
[RESOLVED] Richtextbox RTF - I learned something
Working on an application that reads RTF. In the past when working with Richtextboxes we have found that applications are faster using a RTB that mirrors a RTB on the UI. The mirror RTB is created and disposed on a thread.
What learned is that if I do this
bkgRTB.Rtf = rtbOnTheUI.Rtf
where:
- bkgRTB.Rtf - mirror RTB
- rtbOnTheUI.Rtf - RTB on the UI
The background RTB thinks / is on the UI. It is manifested by CrossThread errors.
The fix was to load the RTF into a string and then load each of the RTB's .Rtf property from that.
-
Aug 19th, 2019, 06:45 PM
#2
Re: Richtextbox RTF - I learned something
This isn't really anything specific to RichTextBox's. If you create two controls on different threads then any code that access a property of both controls must be executed on a thread that does not the handle of at least one of the controls, so a cross-thread exception is inevitable. It doesn't matter whether it is the Rtf properties of RichTextBoxes, the Text properties of TextBoxes, the Value properties of DateTimePickers, the Value properties of NumericUpDowns or something else. The very same rule applies here as with any other control in any other multi-threaded application: when you access a member of a control, you must do it on the thread on which the control's handle was created. If you have two RichTextBoxes that were created on different threads then any of their properties - not just Rtf - must be access only on their respective creating threads.
-
Aug 19th, 2019, 07:22 PM
#3
Re: Richtextbox RTF - I learned something
Not sure I understand that. I'll test the text property tomorrow. If I wasn't clear, the background RTB was created on the background thread. When I assigned the RTF property from the UI RTB I did so from the UI. That worked. It was when I accessed other properties of the background RTB that errors occurred.
-
Aug 20th, 2019, 07:44 AM
#4
Re: Richtextbox RTF - I learned something
Originally Posted by jmcilhinney
This isn't really anything specific to RichTextBox's. If you create two controls on different threads then any code that access a property of both controls must be executed on a thread that does not the handle of at least one of the controls, so a cross-thread exception is inevitable. It doesn't matter whether it is the Rtf properties of RichTextBoxes, the Text properties of TextBoxes, the Value properties of DateTimePickers, the Value properties of NumericUpDowns or something else. The very same rule applies here as with any other control in any other multi-threaded application: when you access a member of a control, you must do it on the thread on which the control's handle was created. If you have two RichTextBoxes that were created on different threads then any of their properties - not just Rtf - must be access only on their respective creating threads.
In the following rtb is a richtextbox created on a background thread, and rtbIN is part of the UI. When I assign the .Rtf property I get errors later in the code when I access rtb properties, e.g. Dim lns() As String = rtb.Lines . When I assigned the .Text property the code runs fine. Seems odd to me.
Code:
'in the background thread
Dim rtb As New RichTextBox
Me.Invoke(Sub()
'rtb.Rtf = rtbIN.Rtf 'causes Cross-thread operation not valid later
rtb.Text = rtbIN.Text 'This works
End Sub)
-
Aug 20th, 2019, 11:16 AM
#5
Re: Richtextbox RTF - I learned something
I would assume that
rtb.Rtf = rtbIn.Rtf
isn't making a copy of the text, it is copy of a reference, so both rtbs are referencing the same Gui object.
Later when you try to use that reference from the other thread, you get the error because you're trying to reference an object created on the Gui thread.
The .Text might work, because .Text is a String, and a String is treated as a Value type, not a reference type. So, both rtb's may be referencing the same string, but because it is treated as a value type, and is immutable, it won't cause a object Cross-thread operation error.
In either case, since it seems like you intend to make a copy of the data, rather than a reference to the data, you shouldn't be doing an assignment like you are. I don't know if the .Rtf has a clone method to create a copy or not. Should look it up, but not curious enough.
-
Aug 20th, 2019, 12:00 PM
#6
Re: Richtextbox RTF - I learned something
Saying Rtf might not be a string is like saying JSON might not be a string... It is... You really should have looked it up. 15 seconds would have saved you some grief.
It does seem odd though. The only thing I can think of is that there's something going on with the internals of the RTB in its rendering. With .Text, it just simply displays the text that's passed to it. With the .Rtf property though, it has to parse it and render it with its formatting. So clearly there's something else going on. But what it is, I couldn't say.
-tg
-
Aug 20th, 2019, 12:03 PM
#7
Re: Richtextbox RTF - I learned something
Originally Posted by passel
I would assume that
rtb.Rtf = rtbIn.Rtf
isn't making a copy of the text, it is copy of a reference, so both rtbs are referencing the same Gui object.
Later when you try to use that reference from the other thread, you get the error because you're trying to reference an object created on the Gui thread.
The .Text might work, because .Text is a String, and a String is treated as a Value type, not a reference type. So, both rtb's may be referencing the same string, but because it is treated as a value type, and is immutable, it won't cause a object Cross-thread operation error.
In either case, since it seems like you intend to make a copy of the data, rather than a reference to the data, you shouldn't be doing an assignment like you are. I don't know if the .Rtf has a clone method to create a copy or not. Should look it up, but not curious enough.
That is the only thing that makes sense, at least it explains the error. The documentation says that .Text and .Rtf are String Properties, though .Text is declared Overrides.
What I ended up doing was reading the RTF into a string and then assigning the string to both Rtf properties.
-
Aug 20th, 2019, 01:16 PM
#8
Re: Richtextbox RTF - I learned something
I wonder if the problem wasn't so much assigning the RTF, but READING the Rtf property...
-tg
-
Aug 21st, 2019, 12:56 PM
#9
Re: Richtextbox RTF - I learned something
The .Rtf and .Text properties are both strings. Why there is a difference seems unknown, but at least it is discussed and there is a workaround should anyone else have the same issue. I'll mark this resolved.
-
Aug 21st, 2019, 05:12 PM
#10
Re: [RESOLVED] Richtextbox RTF - I learned something
Form Level Variables work cross thread, but Control Properties don't...
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
Tags for this Thread
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
|