Cross-thread operation problem for RTF control when used in a thre

G

Guest

In simplified form, I have an RTF control and a timer. I use the timer to do
an autoresave for the RFT control every 5 minutes. Here is the abridged code.

Private Sub tmrAutoRecover_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles tmrAutoRecover.Tick
Dim t As New Threading.Thread(New Threading.ThreadStart(AddressOf
delDoAutoBackup))
t.IsBackground = True
t.Start()
End Sub

Private Sub delDoAutoBackup()
Dim sRTF As String
sRTF = Me.rtfUser.Rtf
WriteAutoRecoverRecord(sRTF) 'Saves to database table
End Sub

This code works as expected in VS 2003 but returns "Cross-thread operation
not valid" error in VS 2005 when populating the sRTF variable. I understand
the problems with multiple threads accessing a control. In my case the
AutoBackup delegate does not change any RTF control property. It only reads
the RTF property.

Is there a way to disable this protection that Microsoft added to VS 2005
that is not needed for my situation? Is there a better way to accomplish this
backup task? One way that works is to make the sRTF variable class level and
set it in the tmrAutoRecover_Tick method before launching the thread.
Unfortunately, if the RTF contains images, it causes a noticeable delay.
Another solution is to stay with VS 2003.
 
L

Lucky

i tried the code you pasted here but i didnt get any error. anyways try
control.Invok() property to get the text. for that you have to define
one method on form that will return you the text. call that method
using control.Invok method. it should work. this is the only way i'm
telling you. by optimizing it you can get more accurate results.
 
G

Guest

To Lucky: You must not have been using VS 2005. Information in MSDN appears
to verify this behavior. Microsoft has added the Backgroundworker control
to handle this situation.

I did more searching and found the following article:
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxmclictl/html/138f38b6-1099-4fd5-910c-390b41cbad35.htm

Below are two examples of code that solves my problem. One uses a delegate.
One uses the backgroundworker control.

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Me.backgroundWorker1.RunWorkerAsync()
End Sub

Private Sub backgroundWorker1_RunWorkerCompleted(ByVal sender As Object,
ByVal e As RunWorkerCompletedEventArgs) Handles
backgroundWorker1.RunWorkerCompleted
Dim s As String = Me.RichTextBox1.Rtf
Debug.Print(s)
End Sub

===============================

Delegate Sub ReadRTFCallback()

Private Sub setTextSafeBtn_Click(ByVal sender As Object, ByVal e As
EventArgs) Handles setTextSafeBtn.Click
Me.demoThread = New Thread(New ThreadStart(AddressOf
Me.ThreadProcSafe))
Me.demoThread.Start()
End Sub

Private Sub ThreadProcSafe()
Me.ReadRTF()
End Sub


Private Sub ReadRTF()
If Me.RichTextBox1.InvokeRequired Then
Dim d As New ReadRTFCallback(AddressOf ReadRTF)
Me.Invoke(d, New Object() {})
Else
Dim s As String = Me.RichTextBox1.Rtf
Debug.Print(s)
End If
End Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top