powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
14 сообщений из 14, страница 1 из 1
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935185
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну т.е. грубо так
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
        Dim message As New MailMessage()
        With message
...
          .Attachments.Add(New Attachment(attach)) 'attach-путь к отправляемому файлу
        End With
        Dim client As New SmtpClient()
        With client
          ...
          If IsNothing(m_CallbackFunction) Then
             .Send(message)
            'в этом варианте точно могу здесь удалить attach
            Return True
          Else
            AddHandler client.SendCompleted, m_CallbackFunction
            .SendAsync(message, m_emailToken)
            'А вот здесь могу??? удалить attach???
            Return True
          End If
        End With



Код выполняется в тике таймера типа так (схематично, к синтаксису не предираться), таймер на время выполнения кода блокируется, т.е. если есть несколько заданий на отправку мыла, то отправляется сразу циклом:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
   Private Sub TimerMail_Tick(sender As Object, e As EventArgs) Handles TimerMail.Tick
     TimerMail.Enabled = False
     Do
        If (есть чего отправлять)
           отправляем кодом выше
        Else
           Exit Do
        End If
     Loop
     TimerMail.Enabled = True
  End Sub



Результат отправки мне на самом деле не важен, я его нигде не логирую, эта хрень достаточно хорошо работает чтобы этим заниматься.
attach -временный и его надо удалять сразу после отправки

Если я делаю .Send(message)
то я конечно точно могу удалить attach следующей строчкой
Но .Send жестко клинит.
Вопрос: что он клинит? только процедуру ЭТОГО таймера (если только этого то меня возможно устроит)? Или например другие таймеры на этой форме тоже?

Вариант с .SendAsync мне конечно больше нравится. Типа отправил и забыл.
Но могу ли я следующей строчкой удалить attach?
И если нет, то как его удалять? В CallBack? Но туда надо как-то передать чего удалять.
В письмо я всегда вкладываю файл %temp%\RandomFolder\FILE.ext
%temp% -системная временная папка
RandomFolder -уникально генерируемое имя сабфолдер в temp, вызывающая процедура знает RandomFolder
FILE.ext -собственно attach
По сути после отправки я должен сделать (и это здорово что в .Net есть штука позволяющая удалить непустую папку без танцев):
Код: vbnet
1.
Try : IO.Directory.Delete(IO.Path.Combine(IO.Path.GetTempPath, RandomFolder), True) : Catch : End Try



Ну т.е. какие советы?

P.S. Хотя нет, соврал немного. Результат я таки логирую (по желанию).
Т.е. мне надо дождаться результата отправки перед отправкой следующего мыла (параллельной отправки не надо).
Но при этом каменного висяка тоже не надо (если только внутри этого таймера, не более).
Сделать .SendAsync и менять флаг из callback, ожидая его циклом через Application.DoEvents() в тек. процедуре, потом удалить файл?
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935295
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Вариант с .SendAsync мне конечно больше нравится. Типа отправил и забыл.
Но могу ли я следующей строчкой удалить attach?
нет. в обработчике SendCompleted удаляй файл, оттуда же и логгируй
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935468
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не все так просто как хотелось:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Try : IO.File.Copy(origfile, IO.Path.Combine(IO.Path.GetTempPath, origfileShortName, "FILE.pdf"), True) : Catch : End Try
attachfile = IO.Path.Combine(IO.Path.GetTempPath, origfileShortName, "FILE.pdf")

message.Attachments.Add(New Attachment(attachfile))

AddHandler client.SendCompleted, m_CallbackFunction
.SendAsync(origfileShortName, origfileShortName)

Private Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
    Dim token As String = CStr(e.UserState)
...
    If IO.Directory.Exists(IO.Path.Combine(IO.Path.GetTempPath, token)) Then
      Try
        IO.Directory.Delete(IO.Path.Combine(IO.Path.GetTempPath, token), True)
      Catch ex As Exception
        Debug.Print(ex.Message) 'Процесс не может получить доступ к файлу "FILE.pdf", так как этот файл используется другим процессом.
      End Try
    End If
End Sub



Он его "закусывает".
Подозреваю что объект message продолжает жить какое-то время и не отдает файл пока мусорщик его не прибрал.
Т.е. папку можно удалить ручками, не закрывая приложение, но только через какое-то время.
Попробовать сделать ему Dispose() сразу после .SendAsync? Или обернуть в Using?
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935474
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Подозреваю что объект message ... не отдает файл
Попробовать сделать ему Dispose() сразу после .SendAsync? Или обернуть в Using?
Не вариант.
Файл удаляется, но мыло не отправляется (ну понятно, если я его заранее грохнул).
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
14.04.2015 7:31:59	Sending mail asynchronously
		Token=140420150731146843887
14.04.2015 7:31:59	Sending mail asynchronously...waiting for the result
-------------------------
-------------------------
14.04.2015 7:32:00	Sending mail asynchronously...Failed. Error : Сбой при отправке сообщения электронной почты.
		Token=140420150731146843887
-------------------------


Замкнутый круг. Как мне грохнуть "message" из CallBack (чтоб суметь удалить attach)? Я ведь его создавал в вызывающей процедуре.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935505
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Попробуй диспоузить мессаже в колбэке

Диспоузить сразу после sendasync - дает вполне ожидаемый результат
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935509
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77, попробуй передать методу SendAsync в качестве userState экземпляр класса со своим строковым токеном и экземпляром MailMessage. Тогда мы сможем вызвать Dispose() для MailMessage и это должно отпустить аттачмент.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935528
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazile,Изопропил
Уже сделал, помогает. Хотя извращение еще то.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
  <StructLayout(LayoutKind.Sequential)>
  Public Structure MyEmailToken
    Dim msg As System.Net.Mail.MailMessage
    Dim token As String
  End Structure

            AddHandler client.SendCompleted, m_CallbackFunction
            Dim MyToken As MyEmailToken
            MyToken.msg = message
            MyToken.token = m_emailToken 'здесь я в данной задаче передаю origfileShortName из %temp%\origfileShortName\attach.ext
            .SendAsync(message, MyToken)

  Private Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
    ' Get the unique identifier for this asynchronous operation.
    Dim MyToken As MyEmailToken = CType(e.UserState, MyEmailToken)
    MyToken.msg.Dispose() 'удаляем message чтобы удалить папку с attach
...
    'удаляем временную папку с файлом 
    If IO.Directory.Exists(IO.Path.Combine(IO.Path.GetTempPath, MyToken.token)) Then
      Try : IO.Directory.Delete(IO.Path.Combine(IO.Path.GetTempPath, MyToken.token), True) : Catch : End Try
    End If
  End Sub



Но у меня такие же грабли с CDO.Message (внедрено оба метода, CDO без CallBack-ов)
Код: vbnet
1.
2.
3.
4.
5.
       Dim o_Mess As Object = CreateObject("CDO.Message")

        .AddAttachment(attach)
        .Send()
        'ну и можно удалять (здесь .Send ждет)



И тоже вот не удаляется
В VB6 удалялось таким дебильным кодом (сразу после .Send)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
        'удаляем временную папку с attach
        DeleteFile attach
        Do 'цикл
          DoEvents
          If Len(Dir(GetEnvarVar("temp") & "\" & origfileShortName, vbDirectory)) > 0 Then
            rez = RemoveDirectory(GetEnvarVar("temp") & "\" & origfileShortName)
            If (rez = 1) Then 'если удалили выходим
              Exit Do
            End If
          Else 'если не сущ.выходим
            Exit Do
          End If
        Loop


(причем цикл там был излишеством, сам файл то сразу удалялся - здесь проблема в нем)

А в .Net почему-то закусывает.
o_Mess =Nothing -не помогает
Более того, прав на чтение вкладки Security для файла attach не дает пока приложение не закроешь.

Как COM объект грохнуть? После .Send
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935562
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Уже сделал, помогает. Хотя извращение еще то.
Замени Structure на class т.к. вызов SendAsync все равно приведет к упаковке и никакой экономии ты не получаешь.

Дмитрий77Как COM объект грохнуть? После .Send
Marshal.FinalReleaseComObject ?

Дмитрий77o_Mess =Nothing -не помогает
И не должен т.к. обнуление ссылочной переменной не имеет никакой магии.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935624
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileДмитрий77Уже сделал, помогает. Хотя извращение еще то.
Замени Structure на class т.к. вызов SendAsync все равно приведет к упаковке и никакой экономии ты не получаешь.
Да я здесь за экономией не гонюсь. Работает -хорошо. Покажи код как сделать, чет я слово класс недолюбливаю в любом контексте.

bazileДмитрий77Как COM объект грохнуть? После .Send
Marshal.FinalReleaseComObject ?
Не помогает.
Но самое интересное что IO.Directory.Delete выдает исключение,
а сам файл в папке ПРИ ЭТОМ по истечении какого-то времени таки удаляется (через минуту его там нет),
фолдер его содержащая остается навсегда.

Я если честно не вижу разницы между CDO кодом в VB6 и CDO-кодом в .Net.
Зато вижу разницу в том как я это удаляю.
В VB6:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
        'удаляем временную папку с attach
        DeleteFile attach 'СНАЧАЛА ФАЙЛ
        Do 'цикл
          DoEvents
          If Len(Dir(GetEnvarVar("temp") & "\" & origfileShortName, vbDirectory)) > 0 Then
            rez = RemoveDirectory(GetEnvarVar("temp") & "\" & origfileShortName)
            If (rez = 1) Then 'если удалили выходим 'ДОЛБИМ ДО ПОБЕДНОГО
              Exit Do
            End If
          Else 'если не сущ.выходим
            Exit Do
          End If
        Loop



В .Net позарился на рекурсивную типа готовую
Код: vbnet
1.
IO.Directory.Delete (включая содержимое)



М.б. здесь вернуть прежний код?
Сначала файл, потом папка (ну, подолбим самую малость).
Единственное, долбить IO.Directory.Delete через Try...Catch я не рискну - это последнее дело,
в цикл надо тогда вернуть API RemoveDirectory

bazileДмитрий77o_Mess =Nothing -не помогает
И не должен т.к. обнуление ссылочной переменной не имеет никакой магии.

В VB6 магия есть:
Код: vbnet
1.
Set o_Mess =Nothing


В .Net согласен, давно уже понял, что бесполезняк.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935715
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот так удаляет:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
            IO.File.Delete(attach)
            Do 'цикл
              Application.DoEvents()
              If IO.Directory.Exists(IO.Path.Combine(IO.Path.GetTempPath, origfileShortName)) Then
                If RemoveDirectory(IO.Path.Combine(IO.Path.GetTempPath, origfileShortName)) Then
                  Exit Do
                Else
                  Debug.Print("Delete error")
                End If
                'Try
                '  IO.Directory.Delete(IO.Path.Combine(IO.Path.GetTempPath, origfileShortName), False)
                '  Exit Do
                'Catch
                'End Try
              Else 'если не сущ.выходим
                Exit Do
              End If
            Loop


Через кучу Net-исключений или через кучу Debug.Print("Delete error").
И скорее всего в VB6 было тоже самое и Do..Loop там был воткнут чтоб заткнуть проблему. Непорядок короче.
Оно конечно "быстро", но хотелось бы чтоб сразу.
Причем файл то сразу удаляется, без циклов.
А по фолдер надо долбить, вот этого я не понимаю, .attach если и держит, то файл а не папку.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935747
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фу, нашел как сделать грамотно:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
        Dim o_Mess As Object = CreateObject("CDO.Message")

        With o_Mess
...
          .AddAttachment(attach)
...
          .Send()
          .Attachments.DeleteAll() 'принудительно отпускаем аттачменты с миром 
        End With



После этого он не будет препятствовать удалению папки с файлом:
Код: vbnet
1.
2.
3.
            If IO.Directory.Exists(IO.Path.Combine(IO.Path.GetTempPath, origfileShortName)) Then
              Try : IO.Directory.Delete(IO.Path.Combine(IO.Path.GetTempPath, origfileShortName), True) : Catch : End Try
            End If



Скорее всего COM и сам "сбрасывает", но чуть-чуть не успевает. Принудительная отвязка аттачей (после .Send здесь они уже не нужны) сразу освобождает файлы.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Property Attachments As IBodyParts
    read-only
    Member of CDO.Message
    The object's Attachments collection.

Sub DeleteAll()
    Member of CDO.IBodyParts
    Deletes all BodyPart objects in the collection.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38935762
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Покажи код как сделать, чет я слово класс недолюбливаю в любом контексте.
Код: vbnet
1.
2.
3.
4.
5.
6.
Public Class MyEmailToken
    Dim msg As System.Net.Mail.MailMessage
    Dim token As String
End Class

Dim MyToken As New MyEmailToken


Заодно убрал StructLayout т.к. в нём нет никакой необходимости.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38936063
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazile,

Ну будь по твоему, хотя какая разница, больше к Type/Structure привык.
Только тогда уж Public а не Dim.

Ну и я тут подумал стратегически, нефиг token так субъективно использовать
SendMail то я себе на все случаи универсально написал, а уже ковыряю.
Вот CallBack -он под частный случай пишется.
token это token,
лучше запастись param as object и туда писать (в данном случае путь к удаляемой папке с attach, можно целиком)
Это просто частный случай, что у меня здесь имена исходных файлов уникальны,
а в другом применении будет по-другому.

Вот так короче получилось:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
  Public Class MyEmailToken
    Public token As String
    Public msg As System.Net.Mail.MailMessage
    Public param As Object
  End Class

            AddHandler client.SendCompleted, m_CallbackFunction
            Dim MyToken As New MyEmailToken
            MyToken.token = m_emailToken
            MyToken.msg = message
            MyToken.param = m_param 'в m_param в нашем случае передаю полный путь %temp%\subfolder
            .SendAsync(message, MyToken)
 

  Private Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
    ' Get the unique identifier for this asynchronous operation.
    Dim MyToken As MyEmailToken = CType(e.UserState, MyEmailToken)
    MyToken.msg.Dispose() 'удаляем message чтобы удалить папку с attach
    AddLogCDO("-------------------------")
    If e.Error IsNot Nothing Then
      Dim str_err As String = "Error : " & e.Error.Message
      AddLogCDO(Now.ToString & Chr(9) & "Sending mail asynchronously...Failed. " & str_err)
      AddLogCDO(Chr(9) & Chr(9) & "Token=" & MyToken.token)
      AddLogCDO("-------------------------")
    Else
      AddLogCDO(Now.ToString & Chr(9) & "Sending mail asynchronously...Done")
      AddLogCDO(Chr(9) & Chr(9) & "Token=" & MyToken.token)
      AddLogCDO("-------------------------")
    End If
    'удаляем временную папку
    If IO.Directory.Exists(CType(MyToken.param, String)) Then
      Try : IO.Directory.Delete(CType(MyToken.param, String), True) : Catch : End Try
    End If
  End Sub



Ну вроде сделал неспеша 18 тестов во всех комбинациях (3 исходных формата, 3 формата attachment, CDO/Net.Mail),
получил 54 мыла (To,CC,BCC), все дослалось, мусор в %temp% во всех случаях удалился.
Ну плюс частные случаи отработал (это когда вдруг ошибка не доходя до .Send/.SendAsync, в этом случае надо делать Dispose по catch, ну не дослалось, а мусор в темпе то зачем)
Разобрался короче.
...
Рейтинг: 0 / 0
При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
    #38936616
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Разобрался короче.Аллах велик
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / При отправке мыла через System.Net.Mail когда я могу физически удалить attachment?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]