0

I'm building a UI which consists of one main Form with possible instances of additional forms and custom classes. What I'm still missing is a consistent way of logging errors. So what I do is I created try-catch blocks around all code that could generate errors, mainly the things that process incoming data. I'm receiving a constant data flow (JSON) from some site, so the built in threading functionality of the framework makes it a multi threading application. Again, the multi threading part is the built-in functionality, I'm not doing this myself actively, since I'm not that smart yet, from a C# point of view. ;)

For the logging part, I've got the code below from here. Even though I'm not so smart yet, I do think I actually understand what is going on there. My concern/question however, is this: how do I implement a Multi-Threading logging mechanism that writes errors to ONE log file cross-form cross-class.

Here is an example that you can use a reference:

// MyMainForm.cs
namespace MyNameSpace
{
    public partial class MyMainForm : Form
    {
        FooClass MyClass = new FooClass();  //<< errors could occur here
        Form f = new MyForm();              //<< errors could occur here

        ...                                 //<< errors could occur here
    }
}

// FooClass.cs
namespace MyNameSpace
{
    public class FooClass
    {
        public string ErrorGeneratingMethod() 
        {
            try...catch(Exception e) { /* Write to Log file */ }
        }
    }
}

// Don't really know where to put this...
private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();

public void WriteToFileThreadSafe(string text, string context)
{
    string t = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
    string path = Properties.Settings.Default.FQLogFileLocation;

    // Set Status to Locked
    _readWriteLock.EnterWriteLock();
    try
    {
        // Append text to the file
        using (StreamWriter sw = File.AppendText(path))
        {
            sw.WriteLine("[" + t + "]["+ context + "]" + text);
            sw.Close();
        }
    } catch (Exception e)
    {
        MessageBox.Show(e.Message); // Really Exceptional (should never happen)
    }
    finally
    {
        // Release lock
        _readWriteLock.ExitWriteLock();
    }
}

So basically what is important for me to know is where do I put WriteToFileThreadSafe() together with _readWriteLock? And how do I safely use this function in multiple threads in multiple forms and classes?

Thanks a lot in advance for letting me learn from you guru's :)

AGI_rev
  • 129
  • 10
  • how about using bicycle with name `NLog` ? available with NuGet package manager. – Zam Jan 10 '19 at 11:59
  • I will investigate... But something I didn't mention, performance is very important so the more simple it is the better... – AGI_rev Jan 10 '19 at 12:29
  • using `NLog` is very very simple and it's very powerful logging tool. – Zam Jan 10 '19 at 12:36
  • If you want to handle it yourself, consider SpinLock vs normal locking https://learn.microsoft.com/en-us/dotnet/standard/threading/how-to-use-spinlock-for-low-level-synchronization. The performance question is not something that can be answered without profiling your sample case. – Bobo Jan 10 '19 at 12:41
  • Another important consideration is if the logging should block UI thread => sync/async logging. You probably do not want your UI to wait for the file write, so Async should be the choice by default. – Bobo Jan 10 '19 at 12:44
  • I'm currently investigating the NLog option suggested by Zam, and so far so good. Looks like a good way to go. I also read that it is the best performing logging framework around so I just need some time to test it thoroughly... – AGI_rev Jan 10 '19 at 13:13

0 Answers0