I keep getting this error:
The process cannot access the file 'D:\Gasper\Netcool\GA000162.200' because it is being used by another process.
And I have tried everything to safely delete this file. Everything. What Am i doing wrong?

using System;
using System.Net;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Configuration;
using System.IO;
using System.Threading;
using Lextm.SharpSnmpLib;
using Mono.Options;
using Lextm.SharpSnmpLib.Messaging;
using Lextm.SharpSnmpLib.Security;
using System.Net.Mail;

namespace AptraSNMPMessenger
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
        private Thread _thread;
        protected override void OnStart(string[] args) // Spawn a new thread for the mere purpose of doing the job
        {
            try
            {
              // var dir = @"C:\Gasper\Netcool";
              //  if (!System.IO.Directory.Exists(dir))
              //      System.IO.Directory.CreateDirectory(dir);
                _thread = new Thread(WorkerThreadFunc);
                _thread.Name = "My Worker Thread";
                _thread.IsBackground = true;
                _thread.Start();
            }
            catch (System.Exception ThreadStart)
            {
                File.AppendAllText(@"C:\Gasper\ThreadStart.txt", ThreadStart.Message);
                Email(@"D:\Gasper\ThreadStart.txt");
            }
        }

        void WorkerThreadFunc()
        {
            try
            {
                while (!_shutdownEvent.WaitOne(0))
                {
                    try
                    {
                        string TicketStatus = "";
                        string ATMID = "";
                        string StatusCode = "";
                        string EventDescription = "";
                        string DateofEvent = "";
                        string TimeofEvent = "";
                        string Record = "";
                        string ActionCode = "";
                        string temp = "";
                        string Ticket = "";

                        List<FileInfo> Files = new List<FileInfo>();
                        System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(ConfigurationSettings.AppSettings["WatchPath"]);

                        foreach (System.IO.FileInfo f in dir.GetFiles("*.*"))
                        {// Gets all files in the directory
                            Files.Add(f);
                        }

                        for (int j = 0; j < Files.Count; j++)
                        {// Loop to make sure that we running through all files, if there are X number files in the folder, then this loop will run 20 times
                            int i = 0;
                            System.IO.StreamReader inputfile = new System.IO.StreamReader(dir + "\\" + Files[j].ToString());
                            do
                            {// extract data from each file and store it in variables to send to the SNMP function later
                                Record = inputfile.ReadLine();
                                if (Record == null)
                                    break;
                                if (Record.Contains("UPDATE"))
                                {
                                    TicketStatus = "ENTRYUPDATE";
                                }
                                if (Record.Contains("OPEN"))
                                {
                                    TicketStatus = "ENTRYOPEN";
                                }
                                if (Record.Contains("CLOSE"))
                                {
                                    TicketStatus = "ENTRYCLOSE";
                                }
                                if (Record.Contains("ATMID") && i == 0)
                                {
                                    ATMID = Record.Remove(0, 8);
                                    i++;
                                }
                                if (Record.Contains("CODE") && i == 1)
                                {
                                    StatusCode = Record.Remove(0, 7);
                                    i++;
                                }
                                if (Record.Contains("DESCRIPTION") && i == 2)
                                {
                                    EventDescription = Record.Remove(0, 14);
                                    i++;
                                }
                                if (Record.Contains("START"))
                                {
                                    temp = Record.Remove(0, 7);
                                    TimeofEvent = temp.Remove(0, 11);
                                    DateofEvent = temp.Substring(1, 10);
                                    DateofEvent = DateofEvent.Replace("/", "");
                                }
                                if (Record.Contains("TKT"))
                                {
                                    Ticket = Record.Remove(0, 7);
                                }
                                if (Record.Contains("Action") && i == 3)
                                {
                                    ActionCode = Record.Remove(0, 14);
                                    break; // Break because we have all the information that we need
                                }
                            } while (Record != null);

                            try
                            {// Take those Variables and send it to my SNMP function
                                inputfile.Close();
                                SNMPMessageSend(ATMID, StatusCode, ActionCode, EventDescription, Ticket, DateofEvent, TimeofEvent, TicketStatus);
                                SafeDelete(dir + "\\" + Files[j].ToString()); // Try to delete the file
                            }
                            catch (System.Exception SendCloseDelete)
                            {
                                using (StreamWriter writer = File.AppendText((@"D:\Gasper\SendCloseDeleteException.txt")))
                                {
                                    writer.WriteLine(SendCloseDelete.Message);
                                }

                                Email(@"D:\Gasper\SendCloseDeleteException.txt");
                            }
                        }
                        System.Threading.Thread.Sleep(5000);// Sleep for 5 seconds
                    }
                    catch (IOException ioex)
                    {
                        using (StreamWriter writer = File.AppendText((@"D:\Gasper\FileException.txt")))
                        {
                            writer.WriteLine(ioex.Message);
                        }

                        Email(@"D:\Gasper\FileException.txt.txt");
                    }

                    catch (System.Exception OuterException)
                    {
                        using (StreamWriter writer = File.AppendText((@"D:\Gasper\OuterException.txt")))
                        {
                            writer.WriteLine(OuterException.Message);
                        }

                        Email(@"D:\Gasper\OuterException.txt");
                    }
                }// the X number files are complete, so now we can read the next number of files in the folder and repeat the process
            }
            catch (System.Exception SNMPError)
            {
                using (StreamWriter writer = File.AppendText((@"D:\Gasper\SNMPError.txt")))
                {
                    writer.WriteLine(SNMPError.Message);
                }

                Email(@"D:\Gasper\SNMPError.txt");
                GC.Collect();
                WorkerThreadFunc(); // this will ensure that the Service keeps running.
            }
        }

        public bool SafeDelete(string path)
        {
            while (true)
            {
                try
                {
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                        return true; // if the file was successfully deleted, then we can go to my WorkerThreadFunc method
                    }
                }
                catch (Exception ex)
                {
                    Thread.Sleep(100);  // else, if it did not delete, then go through this loop until it gets deleted
                }
            }
        }

        private static void SNMPMessageSend(string ATMID, string StatusCode, string ActionCode,
               string EventDescription, string Ticket, string DateofEvent, string TimeofEvent, string TicketStatus)
        {
            try
            {
                IPAddress address = IPAddress.Parse(ConfigurationSettings.AppSettings["IP"]); // Prod IP in config file
                int port = int.Parse(ConfigurationSettings.AppSettings["Port"]); // Port in config file
                List<Variable> objects = new List<Variable>();

                // (1) add source system
                ObjectIdentifier oidSourceSystem = new ObjectIdentifier(ConfigurationSettings.AppSettings["oidSourceSystem"]);
                ISnmpData dataSourceSystem;
                dataSourceSystem = new OctetString(ConfigurationSettings.AppSettings["dataSourceSystem"]);
                Variable SourceSystem = new Variable(oidSourceSystem, dataSourceSystem);
                objects.Add(SourceSystem);

                // (2) add ATM ID
                ObjectIdentifier oidATMId = new ObjectIdentifier(ConfigurationSettings.AppSettings["oidATMId"]);
                ISnmpData dataATMId;
                dataATMId = new OctetString(ATMID);
                Variable ATMId = new Variable(oidATMId, dataATMId);
                objects.Add(ATMId);

                // (3) add ATM status code
                ObjectIdentifier oidATMStatusCode = new ObjectIdentifier(ConfigurationSettings.AppSettings["oidATMStatusCode"]);
                ISnmpData dataATMStatusCode;
                dataATMStatusCode = new OctetString(StatusCode);
                Variable ATMStatusCode = new Variable(oidATMStatusCode, dataATMStatusCode);
                objects.Add(ATMStatusCode);

                // (4) add ATM action code
                ObjectIdentifier oidATMActionCode = new ObjectIdentifier(ConfigurationManager.AppSettings["oidATMActionCode"]);
                ISnmpData dataATMActionCode;
                dataATMActionCode = new OctetString(ActionCode);
                Variable ATMActionCode = new Variable(oidATMActionCode, dataATMActionCode);
                objects.Add(ATMActionCode);

                // (5) add event description
                ObjectIdentifier oidDescription = new ObjectIdentifier(ConfigurationManager.AppSettings["oidDescription"]);
                ISnmpData dataDescription;
                dataDescription = new OctetString(EventDescription);
                Variable Description = new Variable(oidDescription, dataDescription);
                objects.Add(Description);

                // (6) add ticket nr
                ObjectIdentifier oidTicketNr = new ObjectIdentifier(ConfigurationManager.AppSettings["oidTicketNr"]);
                ISnmpData dataTicketNr;
                dataTicketNr = new OctetString(Ticket);
                Variable TicketNr = new Variable(oidTicketNr, dataTicketNr);
                string Tick = Ticket.ToString();
                objects.Add(TicketNr);

                // (7) add event date
                ObjectIdentifier oidEventDate = new ObjectIdentifier(ConfigurationManager.AppSettings["oidEventDate"]);
                ISnmpData dataEventDate;
                dataEventDate = new OctetString(DateofEvent);
                Variable EventDate = new Variable(oidEventDate, dataEventDate);
                objects.Add(EventDate);

                // (8) add event time
                ObjectIdentifier oidEventTime = new ObjectIdentifier(ConfigurationManager.AppSettings["oidEventTime"]);
                ISnmpData dataEventTime;
                dataEventTime = new OctetString(TimeofEvent);
                Variable EventTime = new Variable(oidEventTime, dataEventTime);
                objects.Add(EventTime);

                ObjectIdentifier TickStat = new ObjectIdentifier(ConfigurationManager.AppSettings["TicketStatus"]);
                ISnmpData TicketStat;
                TicketStat = new OctetString(TicketStatus);
                Variable TicketStatus1 = new Variable(TickStat, TicketStat);
                objects.Add(TicketStatus1);

                // (9) send a message now
                Messenger.SendTrapV2(0, VersionCode.V2, new IPEndPoint(address, port),
                    new OctetString("public"),
                    new ObjectIdentifier(new uint[] { 1, 3, 6, 1, 4, 1, 8484, 1 }),
                    0,
                    objects);
            }
            catch (System.Exception ex)
            {
                File.AppendAllText(@"D:\Work Tasks\SNMPException.txt", ex.Message);
            }
        }

        private void Email(string attachments)
        {
            System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
            //message.To.Add("");
            message.To.Add(ConfigurationSettings.AppSettings["EmailTo"]);
            //message.Subject = "SNMP Error";
            message.Subject = ConfigurationManager.AppSettings["Subject"];
            message.From = new System.Net.Mail.MailAddress("");
            message.Body = "Restart the AptraSNMPMessenger service please";
            System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("", 25);
            smtp.UseDefaultCredentials = true;
            smtp.EnableSsl = false;
            System.Net.Mail.Attachment attachment;
            attachment = new System.Net.Mail.Attachment(attachments);
            message.Attachments.Add(attachment);
            smtp.Send(message);
        }

        protected override void OnStop()
        {// give the thread 3 seconds to stop
            _shutdownEvent.Set();
            if (!_thread.Join(3000))
            { 
                _thread.Abort();
            }
       }
    }
}

Dani AI

Generated

This looks like a classic file-lock race: either the service itself sometimes leaves a handle open, or the external producer hasn’t finished writing when the service tries to delete. ’s suggestion to use a handle/lock inspector is the right first step to see which process actually holds the file. Two immediate code smells to address in the service are the lack of guaranteed disposal for readers/streams and an unconditional infinite delete loop.

Make file access deterministic and fail-safe:

  • Always open files with a using block (or try/finally) so streams are closed even on exceptions.
  • Build paths with Path.Combine or use FileInfo.FullName instead of string-concatenating DirectoryInfo.
  • Test that a file is “ready” before processing by attempting an exclusive open with retries, rather than assuming it’s free immediately.

Example readiness check and bounded delete pattern:

bool IsFileReady(string path, int retries = 5, int delayMs = 200)
{
    for (int i = 0; i < retries; i++)
    {
        try { using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None)) return true; }
        catch (IOException) { Thread.Sleep(delayMs); }
    }
    return false;
}
bool TryDelete(string path, int maxAttempts = 20)
{
    for (int i = 0; i < maxAttempts; i++)
    {
        try { File.Delete(path); return true; }
        catch (IOException) { Thread.Sleep(250); }
    }
    return false; // log and move on — don't loop forever
}

Operational/workflow fixes that reduce races:

  • Prefer moving the file to a “processing” folder (File.Move) or renaming it, rather than deleting in place; this reduces contention.
  • If the producer can be changed, use the “write-then-rename” pattern so consumers only see complete files.
  • If using FileSystemWatcher, queue events and process files only after they’ve been idle for a short window (check size stability).
  • Avoid recursive restart of the worker method and avoid calling GC.Collect as a fix; use cooperative cancellation (the ManualResetEvent) and proper logging of full exception stack traces so the actual root cause is visible.

Checklist: replace raw concatenation with Path/FullName, wrap all streams in using, add an IsFileReady gate, replace infinite SafeDelete with bounded TryDelete/backoff, and use a handle-inspector if a lock persists. These steps eliminate the usual locking races and make failures diagnosable.

Try checking what process has your file locked with Process Explorer

Can't see anything obvious that would open a file and lock it in your code.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.