C# 计时器在完成发送电子邮件之前结束

C# 计时器在完成发送电子邮件之前结束,c#,exception,timer,sendmail,C#,Exception,Timer,Sendmail,我必须在计时器体中发送电子邮件,在c#应用程序中,计时器间隔为2秒 try { string[] filePaths = Directory.GetFiles(@"D:\ISS_Homewrok\"); foreach (string filePath in filePaths) { SendEmail(filePath); File.Delete(filePath); } } catch (Exception ex) {

我必须在计时器体中发送电子邮件,在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分钟,但仍会抛出异常!
请提供任何帮助。

您可以尝试使用计时器功能

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();

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


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

您使用的是哪种计时器?在.Net framework中有四种不同类型的计时器,其中一些会生成新线程来处理已用/滴答事件

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

引发已发生事件的信号始终排队等待执行 在线程池线程上,因此事件处理方法可能在其中一个线程上运行 在另一个线程上运行对Stop方法的调用的同时执行线程 线这可能会导致在 调用Stop方法。下一节中的代码示例显示了一个 解决这一竞赛条件的方法

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

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; }

显然,另一个过程(比如文本编辑器或服务)是访问您试图打开的文件。这是一个在编写产品质量代码时必须考虑的典型场景。有一件事你把作业拼错了?另外,为什么要每2秒发送一次电子邮件?您可能需要等到邮件实际发送后再删除文件。
SendMail
是你写的吗?如果没有“MailSend”活动,您可以订阅,您可能需要引入更多的延迟。@ChrisF是的,SendEmail是我为发送电子邮件而编写的一种方法。是否有方法等待电子邮件发送?smtpClient在发送电子邮件时将被阻止。这不是问题,我用的是System.Timers.Timer。我已经尝试了你的代码,但是没有成功,我仍然有相同的异常。好吧,你正在使用多线程计时器。你能告诉我你是如何实现我的代码的吗?我不知道在它之前或之后会有什么。另外,请尝试在File.Delete方法之前添加一个Thread.Sleep(500)。只是一个想法,但在放弃之前我会尝试一下。由于字符数的限制,我无法发布整个方法。但我写了完全相同的代码:(我想计时器再次启动,发送电子邮件还没有结束。你能帮我写一些代码吗,我也熟悉VB.net。我想它可能会工作,但当我到达(File.Delete(filePath))时出现问题,我遇到了异常,我想我需要某种方法来处理文件。