1

我对 C# 很陌生,这是我的第一个问题,请对我温柔

我正在尝试编写一个应用程序来从数据提供者那里捕获一些刻度数据,下面是程序的主要部分

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;

    using (StreamWriter writer = File.AppendText("c:\\log222.txt"))
    {

        writer.Write(myoutput.time.ToString(timeFmt) + ",");
        writer.Write(myoutput.product + "," );
        writer.Write(myoutput.type + "," );
        writer.Write(myoutput.price + ",");
        writer.Write(myoutput.volume + ",");

    }

我已经成功地将数据写入文本文件,但是我知道这个方法在高峰时间每秒会被调用 10000 次,并且打开一个文件并每秒附加很多次是非常低效的,我被指出使用缓冲区或某种,但我不知道该怎么做,我尝试阅读文档但我仍然不明白,这就是我在这里求助的原因。

请给我一些(工作)代码段,以便我可以指出写入方向。谢谢

编辑:我已经尽可能地简化了代码

    using (StreamWriter streamWriter = File.AppendText("c:\\output.txt"))
    {
        streamWriter.WriteLine(string.Format("{0},{1},{2},{3},{4}",
                        e.TimeStamp.ToString(timeFmt),
                        e.Product.ToString(),
                        Enum.GetName(typeof(ZenFire.TickType), e.Type),
                        e.Price,
                        e.Volume));
    }

ED 告诉我要把我的流放到一个字段中,语法是什么样的?任何人都可以发布一些代码来帮助我吗?多谢

4

3 回答 3

1

您需要为流创建一个字段而不是局部变量。在构造函数中初始化一次,不要忘记在某个地方关闭它。最好实现IDisposable接口并在Dispose()方法中关闭流。

一次性

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*/ }
}
于 2012-05-31T06:27:12.813 回答
0

你可以做很多事情

第 1 步。确保不要进行多次 io 调用和字符串连接。

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, 
  ...);

无论您当前的表现如何,我都建议您这样做。我还做了一些外观上的更改(变量/属性/类名大小写。您应该查看变量和属性之间的区别及其推荐的大小写等)

第 2 步。分析您的表现,看看它是否符合您的要求。如果是这样,则无需再做任何事情。如果性能仍然太差,你可以

  • 保持文件打开并在处理程序关闭时将其关闭。
  • 写入缓冲区并定期刷新它。
  • 使用像log4net这样的记录器框架,它会在内部为您处理上述问题,并处理诸如从多个线程访问日志文件之类的棘手问题。
于 2012-05-31T06:29:57.167 回答
-2

我会使用 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);
        }

如果您@在字符串之前使用,则不必使用 double \

这要快得多 - 您只向文件写入一次而不是 5 次。此外,您不要将+运算符与字符串一起使用,这不是最快的操作;)

另外——如果这是多线程应用程序——你应该考虑使用一些锁。它会阻止应用程序尝试从例如写入文件。一次2个线程。

于 2012-05-31T06:24:25.100 回答