write file need to optimised for heavy traffic

后端 未结 3 751
一个人的身影
一个人的身影 2021-01-23 14:42

i am very new to C#, and this is my first question, please be gentle on me

I am trying to write a application to capture some tick data from the data provider, below is

相关标签:
3条回答
  • 2021-01-23 15:25

    I would use String.Format:

    using (StreamWriter writer = new StreamWriter(@"c:\log222.txt", true))
            {
                writer.AutoFlush = true;
                writer.Write(String.Format("{0},{1},{2},{3},{4},", myoutput.time.ToString(timeFmt), 
                    myoutput.product, myoutput.type, myoutput.price, myoutput.volume);
            }
    

    If you use @ before string you don't have to use double \.

    This is much faster - you write only once to the file instead of 5 times. Additionally you don't use + operator with strings which is not the fastest operation ;)

    Also - if this is multithreading application - you should consider using some lock. It would prevent application from trying to write to the file from eg. 2 threads at one time.

    0 讨论(0)
  • 2021-01-23 15:46

    There are many things you can do

    Step 1. Make sure you don't make many io calls and string concatenations.

    Output myOutput = new Outoput(e); // Maybe consruct from event args?
    
    // Single write call, single string.format
    writer.Write(string.Format("{0},{1},{2},{3},{4},{5}", 
      myOutput.Time.ToString(), 
      myOutput.Product, 
      ...);
    

    This I recommend regardless of what your current performance is. I also made some cosmetic changes (variable/property/class name casing. You should look up the difference between variables and properties and their recommended case etc.)

    Step 2. Analyse your performance to see if it does what you want. If it does, no need to do anything further. If performance is still too bad, you can

    • Keep the file open and close it when your handler shuts down.
    • Write to a buffer and flush it at regular intervals.
    • Use a logger framework like log4net that internally handles the above for you, and takes care of hairy issues like access to the log file from multiple threads.
    0 讨论(0)
  • 2021-01-23 15:47

    You need to create a field for the stream instead of a local variable. Initialize it in constructor once and don't forget to close it somewhere. It's better to implement IDisposable interface and close the stream in Dispose() method.

    IDisposable

    class MyClass : IDisposable {
        private StreamWriter _writer;
    
        MyClass() {
            _writer = File.App.....;
        }
    
        void zf_TickEvent(object sender, ZenFire.TickEventArgs e)
        {
    
            output myoutput = new output();
    
            myoutput.time = e.TimeStamp;
            myoutput.product = e.Product.ToString();
            myoutput.type = Enum.GetName(typeof(ZenFire.TickType), e.Type);
            myoutput.price = e.Price;
            myoutput.volume = e.Volume;
    
    
            _writer.Write(myoutput.time.ToString(timeFmt) + ",");
            _writer.Write(myoutput.product + "," );
            _writer.Write(myoutput.type + "," );
            _writer.Write(myoutput.price + ",");
            _writer.Write(myoutput.volume + ",");
    
        }
    
        public void Dispose() { /*see the documentation*/ }
    }
    
    0 讨论(0)
提交回复
热议问题