2014-10-10 128 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