Issue writing to single file in Web service in .NET

前端 未结 11 1785
天涯浪人
天涯浪人 2020-12-10 17:37

I have created a webservice in .net 2.0, C#. I need to log some information to a file whenever different methods are called by the web service clients.

The problem

相关标签:
11条回答
  • 2020-12-10 17:41

    Alternatively, you might want to do error logging into the database (if you're using one)

    0 讨论(0)
  • 2020-12-10 17:43

    Koth,

    I have implemented Mutex lock, which has removed the "stack overflow" error. I yet have to do a load testing before I can conclude whether it is working fine in all cases.

    I was reading about Mutex objets in one of the websites, which says that Mutex affects the performance. I want to know one thing with putting lock through Mutex.

    Suppose User Process1 is writing to a file and at the same time User Process2 tries to write to the same file. Since Process1 has put a lock on the code block, will Process2 will keep trying or just die after the first attempet iteself.?

    thanks pradeep_tp

    0 讨论(0)
  • 2020-12-10 17:48

    Trouble with all the approached tried so far is that multiple threads can enter the code. That is multiple threads try to acquire and use the file handler - hence the errors - you need a single thread outside of the worker threads to do the work - with a single file handle held open.

    Probably easiest thing to do would be to create a thread during application start in Global.asax and have that listen to a synchronized in-memory queue (System.Collections.Generics.Queue). Have the thread open and own the lifetime of the file handle, only that thread can write to the file.

    Client requests in ASP will lock the queue momentarily, push the new logging message onto the queue, then unlock.

    The logger thread will poll the queue periodically for new messages - when messages arrive on the queue, the thread will read and dispatch the data in to the file.

    0 讨论(0)
  • 2020-12-10 17:50

    You could push the results onto an MSMQ Queue and have a windows service pick the items off of the queue and log them. It's a little heavy, but it should work.

    0 讨论(0)
  • 2020-12-10 17:51

    Joel: When you say "queue line" do you mean creating a separate thread that runs in a loop to keep checking the queue as well as write to a file when it is not locked?

    Yeah, that's basically what I was thinking. Have another thread that has a while loop until it can get access to the file and save, then end.

    But you would have to do it in a way where the first thread to start looking gets access first. Which is why I say queue.

    0 讨论(0)
  • 2020-12-10 17:56

    To know what I am trying to do in my code, following is the singletone class I have implemented in C#

    public sealed class FileWriteTest {

    private static volatile FileWriteTest instance;
    
    private static object syncRoot = new Object();
    
    private static Queue logMessages = new Queue();
    
    private static ErrorLogger oNetLogger = new ErrorLogger();
    
    private FileWriteTest() { }
    
    public static FileWriteTest Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new FileWriteTest();
                        Thread MyThread = new Thread(new ThreadStart(StartCollectingLogs));
                        MyThread.Start();
    
                    }
                }
            }
    
            return instance;
        }
    }
    
    private static void StartCollectingLogs()
    {
    
        //Infinite loop
        while (true)
        {
            cdoLogMessage objMessage = new cdoLogMessage();
            if (logMessages.Count != 0)
            {
                objMessage = (cdoLogMessage)logMessages.Dequeue();
                oNetLogger.WriteLog(objMessage.LogText, objMessage.SeverityLevel);
    
            }
        }
    }
    
    public void WriteLog(string logText, SeverityLevel errorSeverity)
    {
        cdoLogMessage objMessage = new cdoLogMessage();
        objMessage.LogText = logText;
        objMessage.SeverityLevel = errorSeverity;
        logMessages.Enqueue(objMessage);
    
    }
    

    }

    When I run this code in debug mode (simulates just one user access), I get the error "stack overflow" at the line where queue is dequeued.

    Note: In the above code ErrorLogger is a class that has code to write to the File. objMessage is an entity class to carry the log message.

    0 讨论(0)
提交回复
热议问题