2014-10-10 85 views
1

我正在使用YAMLDotNet库,并试图让YamlVisitor类触发它的事件,就像它到达每个节点类型的开始和结尾时一样。 这将工作正常,如果流是一个StreamReader,使用文件或字符串,但如果我使用serialPort流它会卡住(等待流结束我假设??)YAML流延迟读取

我的流是数据流经串口,没有确定的结束。

我希望能够在每个YAML节点开始和结束时调用一个函数,因为它们通过流。

这里是我的尝试:

static void Main(string[] args) 
{ 
    using (var sp = new SerialPort("COM1", 600, Parity.Odd, 8, StopBits.One)) 
    { 
     sp.Open(); 

     TextReader tr = new StreamReader(sp.BaseStream); 
     var yaml = new YamlStream(); 

     // try assigning an instance of TracingVisitor before loading the stream... 
     yaml.Accept(new TracingVisitor()); 

     // execution hangs at the following line 
     // waiting for something to indicate end of stream??? 
     yaml.Load(tr); 
    } 
} 

当我喊它只是坐在那里,等待的yaml.Load(tr);。我能够收集到它在进入时处理令牌,但TracingVisitor类中没有任何内容被调用。

这里是将串行数据提供给流的程序。

// 's' is a properly formatted YAML String 
// This code sends the contents of 's' it over COM7 
void Main() 
{ 
    // open a slow serial connection 
    using(var sp = new SerialPort("COM7", 600, Parity.Odd, 8, StopBits.One)) 
    { 
     sp.Open(); 
     sp.Write(s); 
    } 
} 

这里有一个YAML字符串通过

#starting 
--- 
debug: | 
    ->28 
    TxMessages 100, 
    RxMessages 100 
    Loopback Test - US: PASS 
... 
--- 
results: > 
    TxMessages 100, 
    RxMessages 100, 
    Final: PASS 
--- 
results: [1,55,233,546.99] 
... 
--- 
- ignore 
- results: 
    min: -22 
    max: 125 
--- 
list: 
    - 
    TxMessages: 100 
    RxMessages: 100 
    results: [1,55,233,546.99] 
    Loopback Test - US: PASS 
    - results: result String Here! 
... 

回答

1

运行是行不通的,因为YamlStream.Load负载的整个流到内存中。此外,访客不能被转让;当您拨打Accept方法时,访问者访问当前状态。

你可以达到你想要什么,如果你使用Deserializer类,因为它运行在单独的文件,而不是整个流:

var deserializer = new Deserializer(); 
var eventReader = new EventReader(new Parser(new PipeReader(pipe))); 

// Consume the initial StreamStart 
eventReader.Expect<StreamStart>(); 

// Read each document 
do 
{ 
    var data = deserializer.Deserialize<Dictionary<string, object>>(eventReader); 
    Console.WriteLine("{0}\t{1}", DateTime.Now, data["debug"]); 
} 
while(!eventReader.Accept<StreamEnd>()); 

我创建了一个working example in this fiddle

如果每个文档的结构未知,可以反序列化为object。除非你使用的标签,默认的类型将是如下:

  • 映射将反序列化Dictionary<object, object>
  • 序列将反序列化List<object>
  • 标量将反序列化string

查看following fiddle for an example

+1

@ K.R。 ,我已经用解决方法更新了我的答案。理想情况下,我希望能够使用Serializer和Deserializer读取和写入YamlDocument,但这仍然在我的TODO列表中。 – 2014-10-13 22:53:42

+0

deserializer.Deserialize(eventReader)没有指定类型对我更好,因为我的数据有点“随机”结构化,谢谢! – 2014-10-13 23:51:00