THREADS

PHOENIX209E 19/10/2011 14:52:54
#387080
Pessoal!! Ta dificil,nunca mexi com thread,to tomando um salve hahaha!...
Seguinte,eu preciso usar thread pro meu sistema de email,ja tentei de varias maneiras,a forma dele funcionar nao esta dando certo,mudei muito a logica do programa,
No frmprincipal eu tenho um botão que dispara um FOR e envia os parametros pra uma classe que se encarrega de enviar a msg...
FRMPRINCIPAL - segue o fonte:
-------------
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim vFal, vSuc As Integer
Dim vErro, vImg As String
Dim t As Thread
If (TXT_IMG.Text = Nothing) Then
vImg = [Ô]C:\WINDOWS\prc.jpg[Ô]
Else
vImg = TXT_IMG.Text
End If
If (TXT_ASSUNTO.Text = Nothing Or ri.Text = Nothing) Then
MsgBox([Ô]O campo do Assunto e da Mensagem nao podem ser nulos.[Ô], MsgBoxStyle.Critical, [Ô]Campos vazios[Ô])
Else
Try
[txt-color=#007100][ô]CONVERT RICHTEXT PRA HTML[/txt-color]
TXT_MSG.Text = HTML(ri.Rtf)
[txt-color=#007100][ô]ENTRA NO LAÇO NORMALMENTE...[/txt-color]
For i As Integer = 0 To LST_ENVIAR_PARA.Items.Count - 1
[txt-color=#007100][ô]PREEENCHE AS VARIAVEIS DO CONSTRUTOR DA CLASSE DE ENVIO DOS EMAILS[/txt-color]
Dim C_ENVIA As New C_ENVIA_EMAIL(prEmail, TXT_ASSUNTO.Text, TXT_MSG.Text, prSenha, prPorta, prSmtp, prSsl, LST_ENVIAR_PARA.Items(i), vErro, vImg)
[txt-color=#007100][ô] METE A TRHEAD NA MEMORIA JUNTO UM DELEGATE PRA PROCEDURE DENTRO DA CLASSE ENVIA_EMAIL_PROC[/txt-color]
t = New Thread(AddressOf C_ENVIA.Envia_email_proc)
[txt-color=#007100][ô]EXECUTA EM SEGUNDO PLANO[/txt-color]
t.IsBackground = True
[txt-color=#007100][ô]AQUI JÁ ERA PRA EXECUTAR A PROCEDURE,NAO!?!?![/txt-color]
t.Start()
[txt-color=#007100][ô]ERRO PASSADO PELA CLASSE COMO REFERENCIA CASO O HAJA [/txt-color]
If (vErro = Nothing) Then
[txt-color=#007100][ô]EMAILS ENVIADOS COM SUCESSO[/txt-color]
LST_ENVIADOS.Items.Add(LST_ENVIAR_PARA.Items(i) & [Ô] √[Ô])
vSuc += 1
Else
[txt-color=#007100][ô]PROBLEMA NO ENVIO DOS EMAILS[/txt-color]
LST_ERRO.Items.Add(LST_ENVIAR_PARA.Items(i) & [Ô] X Erro: [Ô] & vErro)
vFal += 1
End If
[txt-color=#007100][ô]O NEXT é PASSADO COMO NEM ESTIVESSE AQUI =\ O LAÇO NAO é EXECUTADO,VAI DIRETO PRO END SUB[/txt-color]
Next
MsgBox([Ô]Tarefa concluida com [Ô] & vFal & [Ô] falha(s) e [Ô] & vSuc & [Ô] sucessos de [Ô] & LST_ENVIAR_PARA.Items.Count & [Ô] tentativas.[Ô], MsgBoxStyle.Information, [Ô]Tarefa concluida[Ô])
[txt-color=#007100][ô]NEM NO CATCH CAI!!!!![/txt-color]
Catch ex As Exception
MsgBox([Ô]Erro: [Ô] & Err.Description, MsgBoxStyle.Critical, [Ô]Erro[Ô])
End Try
End If
[txt-color=#007100][ô] DEPOIS DAQUI ELE VAI PRA PROCEDURE MAS JA NO FINAL,NAO PASSA POR VALIDAÇOES DE ERROS NEM NADA =\[/txt-color]
End Sub


-------------------

Na Classe:

   Dim vEmailRemete, vAssunto, vMsg, vSenha, vPorta, vSmtp, vSsl, vDestino, vErro, vImg As String

Public Sub New(ByVal pEmailRemete As String, ByVal pAssunto As String, ByVal pMsg As String, ByVal pSenha As String _
, ByVal pPorta As String, ByVal pSmtp As String, ByVal pSsl As String _
, ByVal pDestino As String, ByRef pErro As String, ByVal pImg As String)
vEmailRemete = pEmailRemete
vAssunto = pAssunto
vMsg = pMsg
vSenha = pSenha
vPorta = pPorta
vSmtp = pSmtp
vSsl = pSsl
vDestino = pDestino
vErro = pErro
vImg = pImg
End Sub

Public Sub Envia_email_proc()
Try
Dim mail As New Mail.MailMessage
mail.From = New MailAddress(vEmailRemete)
mail.To.Add(vDestino)
mail.Subject = vAssunto
Dim vw As AlternateView
vw = AlternateView.CreateAlternateViewFromString(vMsg & [Ô] <br><br><center><img src=[Ô][Ô]cid:imagem[Ô][Ô]></center><br><hr><br>[Ô] & FRM_PRINCIPAL.TXT_ASS.Text, Nothing, [Ô]text/html[Ô])
Dim logo As New LinkedResource(vImg)
logo.ContentId = [Ô]imagem[Ô]
vw.LinkedResources.Add(logo)
mail.AlternateViews.Add(vw)
Dim smtp As New SmtpClient(vSmtp)
smtp.EnableSsl = True
smtp.Port = vPorta
smtp.Credentials = New NetworkCredential(vEmailRemete, vSenha)
smtp.Send(mail)
Catch ex As Exception
vErro = Err.Description
End Try
End Sub


------------


PROBLEMA:
AO ENTRAR NO FOR ELE PASSA AS LINHAS NORMAIS ATé CHEGAR NO T.START() POREM ELE PASSA PELA LINHA E NAO EXECUTA A PROCEDURE DE ENVIO.PRECISA ACABAR O EVENTO PRA ELE EXECUTAR A THREAD????? O FOR NÃO é EXECUTADO CORRETAMENTE,O NEXT FICA [ô]INVALIDO[ô] INDO DIRETO PRO END SUB E DEPOIS SÓ QUE EXECUTA A PROCEDURE [Ô]ENVIA_EMAIL_PROC[ô] .... =\

ja tentei de tudo,e nao funciona!!
Alguem poderia me ajudar?
Grato!!!
PHOENIX209E 20/10/2011 07:39:31
#387142
Ninguem? =\
GUIMORAES 20/10/2011 09:04:31
#387148
Resposta escolhida
Trabalhar com THREADS não é facil.
A princípio, ele fará isto mesmo, passará por todo o codigo, sem fazer loops.
Bom, ja tentou usar o BackgroundWorker?
Creio que ele irá resolver ser problema.

ah, só lembrando, cuidado com as letras maiúsculas.

Abraços.
PHOENIX209E 20/10/2011 09:09:38
#387149
Hmmm entendii!..
Então eu tentei usar o BackWorker mas sempre quando me referencio a um controle ou objeto,ele mostra uma exception
dizendo que não é possivel [ô]cruzar a thread em uso[ô] mas nao tem jeito,de qualquer maneira eu preciso instanciar o smtp client,os controles!! :S
Preciso disso pra hj,meu cronograma já ta vencendo,eu to a semana inteira mexendo com este projeto,e até agora nada.Só falta isso!!
GUIMORAES 20/10/2011 09:18:11
#387154
A parte do exception é facil de resolver, basta colocar o seguinte comando antes de executar a procedure com o backgroundwoker

Control.CheckForIllegalCrossThreadCalls = False

após isto basta charmar o backgroundworker

BackgroundWorker1.RunWorkerAsync()

creio que dará certo.

Abraços
PHOENIX209E 20/10/2011 09:27:26
#387157
Opaaaaaa GUIMARAES123 vou tentar e jaja te Falo!..
Valeu mesmo velho...
PHOENIX209E 20/10/2011 09:51:27
#387158
Tentei,OK este exception já era.
Mas depois surgiram mais uns 3.

Primeiro Exception:
Na hora de converter pra HTML:

  Dim MyWord As Microsoft.Office.Interop.Word.Application
Dim oDoNotSaveChanges As Object = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges
Dim sReturnString As String = [Ô][Ô]
Dim sConvertedString As String = [Ô][Ô]
Try
MyWord = CreateObject([Ô]Word.application[Ô])
MyWord.Visible = False
MyWord.Documents.Add()
Dim doRTF As New System.Windows.Forms.DataObject
doRTF.SetData([Ô]Rich Text Format[Ô], sRTF)
Clipboard.SetDataObject(doRTF)
MyWord.Windows(1).Selection.Paste()
MyWord.Windows(1).Selection.WholeStory()
MyWord.Windows(1).Selection.Copy()
sConvertedString = Clipboard.GetData(System.Windows.Forms.DataFormats.Html)
sConvertedString = sConvertedString.Substring(sConvertedString.IndexOf([Ô]<html[Ô]))
sConvertedString = sConvertedString.Replace([Ô]Â[Ô], [Ô][Ô])
sReturnString = sConvertedString
If Not MyWord Is Nothing Then
MyWord.Quit(oDoNotSaveChanges)
MyWord = Nothing
End If
Catch ex As Exception
If Not MyWord Is Nothing Then
MyWord.Quit(oDoNotSaveChanges)
MyWord = Nothing
End If
MsgBox([Ô]Erro ao converter.Detalhes:[Ô] & vbCrLf & Err.Description, MsgBoxStyle.Critical, [Ô]Erro[Ô])
End Try
Return sReturnString


Neste bloco eu NEGRITEI A LINHA AONDE OCORRE A SEGUINTE EXCEPTION:

Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it.

Aqui ele ta se refirindo ao OLE que estou usando,no caso do clipboard do windows,mas como resolvo isso.
STAThreadattribute marked on it [???????????????????????????] whata hell[ô]s!!!!

caiu no Catch Ok...

Agora no bloco de envio a seguinte exception:

  Public Sub Envia_email_proc()
Try
Dim mail As New Mail.MailMessage
mail.From = New MailAddress(vEmailRemete)
mail.To.Add(vDestino)
mail.Subject = vAssunto
Dim vw As AlternateView
vw = AlternateView.CreateAlternateViewFromString(vMsg & [Ô] <br><br><center><img src=[Ô][Ô]cid:imagem[Ô][Ô]></center><br><hr><br>[Ô] & FRM_PRINCIPAL.TXT_ASS.Text, Nothing, [Ô]text/html[Ô])
Dim logo As New LinkedResource(vImg)
logo.ContentId = [Ô]imagem[Ô]
vw.LinkedResources.Add(logo)
mail.AlternateViews.Add(vw)
Dim smtp As New SmtpClient(vSmtp)
smtp.EnableSsl = True
smtp.Port = vPorta
smtp.Credentials = New NetworkCredential(vEmailRemete, vSenha)
smtp.Send(mail)
Catch ex As Exception
vErro = Err.Description
End Try
End Sub


O erro em que ocorre na linha em NEGRITO é:

An error occurred creating the form. See Exception.InnerException for details. The error is: ActiveX control [ô]8856f961-340a-11d0-a96b-00c04fd705a2[ô] cannot be instantiated because the current thread is not in a single-threaded apartment.


E acaba nem enviado,o problema é que eu nunca mexi com threads antes!!!!

Vc consegue me ajudar?!

Abraços

GUIMORAES 20/10/2011 10:25:05
#387162
Então, coloca o Control.CheckForIllegalCrossThreadCalls = False dentro das subs, pode ser que resolva.

PHOENIX209E 20/10/2011 10:34:14
#387163
nao reolveu cara!.
Ja coloquei uma sugestão que vi no site da microsoft <STAThreadAttribute()>_ na Sub Main mas mesmo assim o erro persiste! ¬¬[ô]
GUIMORAES 20/10/2011 10:56:02
#387165
teria como posar algum exemplo do projeto, que utilize esta parte?
PHOENIX209E 20/10/2011 10:59:07
#387167
O problema com a conversao do RTF pra HTML foi resolvido,agora o problema esta na hora de enviar o email,citado logo acima.

An error occurred creating the form. See Exception.InnerException for details. The error is: ActiveX control [ô]8856f961-340a-11d0-a96b-00c04fd705a2[ô] cannot be instantiated because the current thread is not in a single-threaded apartment.

quando vou instanciar o objeto AlternateView.CreateAlternateViewFromString
Página 1 de 2 [16 registro(s)]
Tópico encerrado , respostas não são mais permitidas