将错误写入Web Service中的文本文件

时间:2017-11-16 15:46:19

标签: c# file soap queue file-writing

我有一个Web服务,它有一个默认的ErrorLog方法,用于将日志添加到Db表。如果在ErrorLog Add或存储过程中发现异常,则返回它无法添加。我想将错误写入服务器上的文本文件,(理论上这绝不会发生)。

在实际实现之前,我意识到很多人很可能会收到错误,所有错误都会失败,所有人都会尝试写入同一个文本文件。

如何在服务上实现队列,以便将消息添加到队列中,另一个服务/作业循环通过此队列并将错误添加到文件中?

我试过寻找例子,其中大部分是非常基本的。我唯一想知道的是如何跟踪队列?我只是创建一个静态类吗?

以下是否有效?

public class ErrorLogging
{

    public ErrorLogging(Error error)
    {
        if (ErrorLoggingQueue._GlobalQueue == null)
        {
            ErrorLoggingQueue._GlobalQueue = new Queue<Error>();
        }

        ErrorLoggingQueue._GlobalQueue.Enqueue(error);
    }
}

public static class ErrorLoggingQueue
{
    public static Queue<Error> _GlobalQueue;
}

// Assume that this class/method gets called every x minutes or seconds from  a job or something.
public class JobClass
{
    public void WriteErrors()
    {
        if (ErrorLoggingQueue._GlobalQueue != null)
        {
            while (ErrorLoggingQueue._GlobalQueue.Count != 0)
            {
                Error error = (Error)ErrorLoggingQueue._GlobalQueue.Dequeue();

                // Do stuff here
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

是的,具有Queue的静态变量将起作用并将在请求之间共享。只需为入队和出队添加锁定以使这些操作成为原子。这些方面的东西:

class YourWebservice
{
    static Queue<Error> _GlobalQueue = new Queue<Error>();
    static readonly object queueLock = new object();
    static Thread errorLogger;

    public void SomeWebserviceMethod()
    {
        //Some code...
        //.
        //.

        //Here we want to log an error
        EnqueueError(new Error());
    }
    private void EnqueueError(Error err )
    {
        lock(queueLock)
        {
            _GlobalQueue?.Enqueue(err);
            if ( errorLogger==null || !(errorLogger?.IsAlive ?? false) )
            {
                errorLogger = new Thread(new ThreadStart(WriteErrors));
                errorLogger?.Start();
            }
        }
    }

    private static Error DequeueError()
    {
        try
        {
            lock (queueLock)
            {
                return  _GlobalQueue?.Dequeue();
            }
        }
        catch(Exception)
        {
            //if we got here it means queue is empty.
        }

        return null;
    }
    private static void WriteErrors()
    {
       Error error = DequeueError();
       while (error!=null)
       {
            //Log error here
            //...
            //..

            error = DequeueError();               
       }
    }
}