Threading / Invoke

K

Kai Wiechers

Hello,
im trying to integrate threading into my project. The threading itself runs
good, but in the sub im launching in the new thread i get an
"NotSupportetException" and VisualStudio tells me i have to do a
controll.invoke. I Added a me.invoke(notification1) to the SMSsenden sub,
but that also seems to be wrong because i get an error that notification1
cant be converted to system.delegate. :( The documentation on the MSDN
doesnt tell me much, but thats maybe my fault... sorry. Im realy new to
threading, so it would be grat if anybody of you has a hint for me! Thanks!

Kai

_____________________________________________

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Try
Dim smsthread As New Thread(AddressOf SMSsenden)
smsthread.Start()
Exit Try

Catch ex As Exception
MsgBox("Beim aufrufen der Sendefunktion ist ein Fehler aufgetreten!",
MsgBoxStyle.Critical, "easySMS")
Exit Sub

End Try
End Sub
_______________________________________________

Public Sub SMSsenden()

Button1.Enabled = False

Notification1.Caption = "easySMS"
Notification1.Text = "Die SMS wird an das Gateway übertragen..."
Notification1.InitialDuration = 0
Notification1.Visible = True

'Text codieren
Dim text As String
text = Textcoder(msg_txt.Text)

'URL erzeugen
Dim debugmode As String
If CheckBox1.CheckState = CheckState.Checked Then
debugmode = "1"
Else
debugmode = "0"
End If

Dim absender As String = ""
If smstyp.SelectedItem = "quality" Then
absender = "&from=" & from_txt.Text
End If

Dim url As String = gateway_txt.Text & "u=" & user_txt.Text &
"&p=" & pass_txt.Text & "&to=" & an_txt.Text & "&text=" & text & "&type=" &
smstyp.SelectedItem & "&return_msg_id=1" & "&debug=" & debugmode & absender
Dim request As WebRequest = WebRequest.Create(url)

'Antwort bekommen
Dim response As HttpWebResponse = CType(request.GetResponse(),
HttpWebResponse)
Dim dataStream As Stream = response.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()

'Antwort Anzeigen
Dim Antwort = responseFromServer
Dim status As String = Strings.Left(Antwort, 3)

Button1.Enabled = True

If status = "100" Then
MsgBox("Versenden erfolgreich." & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "202" Then
MsgBox("Die Empfängernummer ist ungültig." & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "300" Then
MsgBox("Bitte Benutzer und Passwort angeben!" & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "301" Then
MsgBox("Bitte Empfänger angeben!" & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "304" Then
MsgBox("Bitte SMS-Typ wählen!" & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "305" Then
MsgBox("Keinen Text eingegeben!" & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "401" Then
MsgBox("Text ist zu lang!" & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "500" Then
MsgBox("Guthaben zu gering!" & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "900" Then
MsgBox("Benutzer oder Passwort sind falsch!" & vbNewLine,
MsgBoxStyle.Information, "easySMS")
ElseIf status = "902" Then
MsgBox("http API ist für diesen Account nicht aktiviert!" &
vbNewLine, MsgBoxStyle.Information, "easySMS")
Else
MsgBox("Unbekannter fehler!")
End If

Dim msgid As String = Antwort.Substring(4)
'MsgBox(msgid)

'Aufräumen
reader.Close()
dataStream.Close()
response.Close()

If dataset.Tables.Contains("sms") = False Then
Dim smstable As System.Data.DataTable =
dataset.Tables.Add("sms")
smstable.Columns.Add("to", GetType(String))
smstable.Columns.Add("text", GetType(String))
smstable.Columns.Add("type", GetType(String))
smstable.Columns.Add("time", GetType(String))
smstable.Columns.Add("msgid", GetType(String))
smstable.Columns.Add("status", GetType(String))
Dim dr As System.Data.DataRow
dr = smstable.NewRow
Dim Zeit As String = Now
dr("to") = an_txt.Text
dr("text") = msg_txt.Text
dr("type") = smstyp.SelectedItem
dr("time") = Zeit
dr("msgid") = msgid
dr("status") = status
smstable.Rows.Add(dr)
Dim listitem2 As New ListViewItem
listitem2.Text = Zeit
listitem2.SubItems.Add(an_txt.Text)
Dim MSGText As String
MSGText = msg_txt.Text
MSGText = Strings.Left(MSGText, 22) & "..."
listitem2.SubItems.Add(MSGText)
ListView2.Items.Add(listitem2)
ListView2.Items(ListView2.Items.Count - 1).ImageIndex = 0

msg_txt.Text = ""

dataset.WriteXml("\easysms.xml")
Else
Dim smstable As System.Data.DataTable =
dataset.Tables("sms")
Dim dr As System.Data.DataRow
Dim Zeit As String = Now
dr = smstable.NewRow
dr("to") = an_txt.Text
dr("text") = msg_txt.Text
dr("type") = smstyp.SelectedItem
dr("time") = Zeit
dr("msgid") = msgid
dr("status") = status
smstable.Rows.Add(dr)
Dim listitem2 As New ListViewItem
listitem2.Text = Zeit
listitem2.SubItems.Add(an_txt.Text)
Dim MSGText As String
MSGText = msg_txt.Text
MSGText = Strings.Left(MSGText, 22) & "..."
listitem2.SubItems.Add(MSGText)
ListView2.Items.Add(listitem2)
ListView2.Items(ListView2.Items.Count - 1).ImageIndex = 0
msg_txt.Text = ""
'NEU
dataset.WriteXml("\easysms.xml")
End If

If CheckBox3.CheckState = CheckState.Checked Then
Label7.Text = msgid
Timer1.Interval = NumericUpDown1.Value * 1000
Timer1.Enabled = True
End If

Notification1.Visible = False

End Sub
 
D

DrewCE

This seems to be a rite of passage for all .Net 2.0+ developers. You can't
modify the UI from a non-UI thread. Since you are starting a new thread and
then trying to modify UI controls from within that thread, you are getting
the NotSupportedException.

You're on the right track with the Me.Invoke idea.

A quick google yielded the following...

http://social.msdn.microsoft.com/Fo.../thread/5dabedab-4f3d-4e1f-91e3-0b04dad44fc6/

Here's an explanation in C# from a member of the CF team...

http://blogs.msdn.com/davidklinems/archive/2006/03/09/548235.aspx

-Drew
 
S

Simon Hart [MVP]

If you're using .NET CF 3.5 you could use the newly added Action delegate
which saves you the need to define you're own delegate. See here:
http://www.simonrhart.com/2008/11/action-delegate-on-compact-framework-35.html

The code looks like this:

Invoke(new Action(() => MessageBox.Show(args.Name)));

The above will show a message box from a worker thread.

Essentially the action looks like this behind the scenes:

public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4
arg4);
 

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