3

I have a c# windows service which is doing various tasks. Its working perfectly on my local system but as soon as I start it on my product server, its doesn't perform a particular task on it.

This is how my service is structured:

public static void Execute()
{
        try
        {
            // .... some work ....
            foreach (DataRow dr in dt.Rows)
            {
                string cc = dr["ccode"].ToString();
                Task objTask = new Task(delegate { RequestForEachCustomer(cc); });
                objTask.Start();
            }
        }
        catch (Exception ex)
        {
            // Logging in DB + Text File
        }
 }

public static void RequestForEachCustomer(object cc)
{
    try
    {
        // .... some work ....
        foreach (DataRow dr in dt.Rows)
        {
            WriteLog("RequestForEachCustomer - Before Task");
            Task objTask = new Task(delegate { RequestProcessing(dr); });
            objTask.Start();
            WriteLog("RequestForEachCustomer - After Task");
        }
    }
    catch (Exception ex)
    {
        // Logging in DB + Text File
    }
}

public static void RequestProcessing(object dr)
{
    try
    {
        WriteLog("Inside RequestProcessing");
        // .... some work ....
    }
    catch (Exception ex)
    {
        // Logging in DB + Text File
    }
}

Now what happens on the production server is that it logs the last entry in RequestForEachCustomer which is "RequestForEachCustomer - After Task" but it doesn't log the entry from RequestProcessing which mean the task is not starting at all. There are no exceptions in either database or text file.

There are no events logged in window's event viewer either. Also the service keeps working (if I insert another record in database, its processed by the service immediately so the service isn't stuck either. It just doesn't seem to process RequestProcessing task.)

I am baffled by this and it would be great if someone could point out the mistake I am making. Oh, btw did I forgot to mention that this service was working perfectly few days ago on the server and it is still working fine on my local PC.

EDIT :

WriteLog :

public static void WriteErrorLog(string Message)
{
            StreamWriter sw = null;
            try
            {
                lock (locker)
                {    
                    sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\LogFile.txt", true);
                    sw.WriteLine(DateTime.Now.ToString() + ": " + Message);
                    sw.Flush();
                    sw.Close();
                }
            }
            catch (Exception excep)
            {
                try
                {
                    // .... Inserting ErrorLog in DB ....
                }
                catch
                {
                    throw excep;
                }
                throw excep;
            }
        }

I have also logged an entry on OnStop() something like "Service Stopped" and its logs every time I stop my service so the problem couldn't exist in WriteLog function.

NewbieProgrammer
  • 874
  • 2
  • 18
  • 50
  • 2
    It would suggest (from the snippets) that dt.Rows is empty - hence no log. – BugFinder Jun 06 '16 at 10:12
  • What is `WriteLog()`? Perhaps it's not thread safe. – Sinatr Jun 06 '16 at 10:15
  • Nope. I can assure you that dt.Rows is not empty. – NewbieProgrammer Jun 06 '16 at 10:15
  • @BugFinder, it can't be empty to see `"RequestForEachCustomer - After Task"` (this occurs inside loop, so `dt.Rows` is not empty). – Sinatr Jun 06 '16 at 10:16
  • What changed recently? – jdweng Jun 06 '16 at 10:17
  • How many tasks do you create? Try to specify [`TaskCreationOptions.LongRunning`](http://stackoverflow.com/q/5295265/1997232). – Sinatr Jun 06 '16 at 10:22
  • 2
    You start the task, but you never `await` it. This means that any exceptions thrown inside the task will never be seen, unless you explicitly catch and log them inside the delegate (which your extensive error handling outside seems to imply that you don't...). What does the actual delegate `RequestProcessing` look like? – Tomas Aschan Jun 06 '16 at 10:24
  • 2
    You dont get the exception if it is thrown within the task. Use `objTask.ContinueWith(t => /* log t.Exception */, TaskContinuationOptions.OnlyOnFaulted)` to log the actual exception. – JanDotNet Jun 06 '16 at 10:25
  • @TomasLycken, `RequestProcessing` has inner `try/catch` block (shouldn't be any task exception, as they are all catched by `catch(Exception ex)`), but your idea might be correct: what is logged when you have exception? Does *"There are no exceptions in either database or text file"* means what you log exception there and you don't see it in the log? – Sinatr Jun 06 '16 at 10:30
  • You don't have the credentials to write a file on server. The logs are being written to the folder were the executable is located. Try writing to the disk space you have permission to write. – jdweng Jun 06 '16 at 10:30
  • @TomasLycken I thought so too...the try catch block should have handled the exception and logged it. "There are no exceptions in either database or text file" means that I am not able to tell whether my code generated any exception or not as I don't see any logs in database or text file. – NewbieProgrammer Jun 06 '16 at 10:38
  • @jdweng but the service is writing all other entries just fine in the text file. I don't think its a permission issue. – NewbieProgrammer Jun 06 '16 at 10:39
  • @Sinatr if there is any exception I do get a log in text file. But in this case, there is none. – NewbieProgrammer Jun 06 '16 at 10:42
  • Are you sure? Check the date of the log file. I bet you copied the log file from the local system and no writes are occurring since you moved application to server. – jdweng Jun 06 '16 at 11:00

1 Answers1

0

I suggest you refactor your code as in this MSDN example. What bother me in your code is, you never wait for tasks to finish anywhere.

The following example starts 10 tasks, each of which is passed an index as a state object. Tasks with an index from two to five throw exceptions. The call to the WaitAll method wraps all exceptions in an AggregateException object and propagates it to the calling thread.

Source : Task.WaitAll Method (Task[])

This line from example might be of some importance :

Task.WaitAll(tasks.ToArray());
Edgars Pivovarenoks
  • 1,526
  • 1
  • 17
  • 31