Showing the changes to Source/Libraries/GSF.Core/Parsing/MultiSourceFrameImageParserBase.cs (1 of 10 files). Show all
Unified · Split
| @@ -17,6 +17,8 @@ · 16 unmodified lines | |||
| 17 | // Edited Comments. | 17 | // Edited Comments. |
| 18 | // 09/14/2009 - Stephen C. Wills | 18 | // 09/14/2009 - Stephen C. Wills |
| 19 | // Added new header and license agreement. | 19 | // Added new header and license agreement. |
| 20 | // 11/01/2012 - J. Ritchie Carroll | ||
| 21 | // Updated to use concurrent dictionaries and new recreate parsed output list. | ||
| 20 | // | 22 | // |
| 21 | //******************************************************************************************************* | 23 | //******************************************************************************************************* |
| 22 | 24 | ||
| @@ -259,6 +261,7 @@ · 236 unmodified lines | |||
| 259 | 261 | ||
| 260 | using GSF.Collections; | 262 | using GSF.Collections; |
| 261 | using System; | 263 | using System; |
| 264 | using System.Collections.Concurrent; | ||
| 262 | using System.Collections.Generic; | 265 | using System.Collections.Generic; |
| 263 | using System.ComponentModel; | 266 | using System.ComponentModel; |
| 264 | using System.Text; | 267 | using System.Text; |
| @@ -303,9 +306,9 @@ namespace GSF.Parsing · 38 unmodified lines | |||
| 303 | 306 | ||
| 304 | // Fields | 307 | // Fields |
| 305 | private ProcessQueue<IdentifiableItem<TSourceIdentifier, byte[]>> m_bufferQueue; | 308 | private ProcessQueue<IdentifiableItem<TSourceIdentifier, byte[]>> m_bufferQueue; |
| 306 | private Dictionary<TSourceIdentifier, bool> m_sourceInitialized; | 309 | private ConcurrentDictionary<TSourceIdentifier, bool> m_sourceInitialized; |
| 307 | private Dictionary<TSourceIdentifier, byte[]> m_unparsedBuffers; | 310 | private ConcurrentDictionary<TSourceIdentifier, byte[]> m_unparsedBuffers; |
| 308 | private List<TOutputType> m_parsedOutputs; | 311 | private readonly List<TOutputType> m_parsedOutputs; |
| 309 | private TSourceIdentifier m_sourceID; | 312 | private TSourceIdentifier m_sourceID; |
| 310 | private bool m_disposed; | 313 | private bool m_disposed; |
| 311 | 314 | ||
| @@ -322,13 +325,14 @@ namespace GSF.Parsing · 10 unmodified lines | |||
| 322 | m_bufferQueue.ProcessException += ProcessExceptionHandler; | 325 | m_bufferQueue.ProcessException += ProcessExceptionHandler; |
| 323 | 326 | ||
| 324 | if (ProtocolUsesSyncBytes) | 327 | if (ProtocolUsesSyncBytes) |
| 325 | m_sourceInitialized = new Dictionary<TSourceIdentifier, bool>(); | 328 | m_sourceInitialized = new ConcurrentDictionary<TSourceIdentifier, bool>(); |
| 326 | 329 | ||
| 327 | m_unparsedBuffers = new Dictionary<TSourceIdentifier, byte[]>(); | 330 | m_unparsedBuffers = new ConcurrentDictionary<TSourceIdentifier, byte[]>(); |
| 331 | m_parsedOutputs = new List<TOutputType>(); | ||
| 328 | 332 | ||
| 329 | // We attach to base class events so we can cumulate outputs per data source and handle data errors | 333 | // We attach to base class events so we can cumulate outputs per data source and handle data errors |
| 330 | base.DataParsed += CumulateParsedOutput; | 334 | base.DataParsed += DataParsed_CumulateParsedOutput; |
| 331 | base.DataDiscarded += ResetDataSourceInitialization; | 335 | base.DataDiscarded += DataDiscarded_ResetDataSourceInitialization; |
| 332 | } | 336 | } |
| 333 | 337 | ||
| 334 | #endregion | 338 | #endregion |
| @@ -399,21 +403,12 @@ namespace GSF.Parsing · 64 unmodified lines | |||
| 399 | } | 403 | } |
| 400 | m_bufferQueue = null; | 404 | m_bufferQueue = null; |
| 401 | 405 | ||
| 402 | if ((object)m_sourceInitialized != null) | ||
| 403 | { | ||
| 404 | m_sourceInitialized.Clear(); | ||
| 405 | } | ||
| 406 | m_sourceInitialized = null; | 406 | m_sourceInitialized = null; |
| 407 | |||
| 408 | if ((object)m_unparsedBuffers != null) | ||
| 409 | { | ||
| 410 | m_unparsedBuffers.Clear(); | ||
| 411 | } | ||
| 412 | m_unparsedBuffers = null; | 407 | m_unparsedBuffers = null; |
| 413 | 408 | ||
| 414 | // Detach from base class events | 409 | // Detach from base class events |
| 415 | base.DataParsed -= CumulateParsedOutput; | 410 | base.DataParsed -= DataParsed_CumulateParsedOutput; |
| 416 | base.DataDiscarded -= ResetDataSourceInitialization; | 411 | base.DataDiscarded -= DataDiscarded_ResetDataSourceInitialization; |
| 417 | } | 412 | } |
| 418 | } | 413 | } |
| 419 | finally | 414 | finally |
| @@ -491,11 +486,8 @@ namespace GSF.Parsing · 71 unmodified lines | |||
| 491 | /// </remarks> | 486 | /// </remarks> |
| 492 | public virtual void PurgeBuffer(TSourceIdentifier source) | 487 | public virtual void PurgeBuffer(TSourceIdentifier source) |
| 493 | { | 488 | { |
| 494 | lock (m_unparsedBuffers) | 489 | byte[] buffer; |
| 495 | { | 490 | m_unparsedBuffers.TryRemove(source, out buffer); |
| 496 | if (m_unparsedBuffers.ContainsKey(source)) | ||
| 497 | m_unparsedBuffers.Remove(source); | ||
| 498 | } | ||
| 499 | } | 491 | } |
| 500 | 492 | ||
| 501 | /// <summary> | 493 | /// <summary> |
| @@ -586,27 +578,20 @@ namespace GSF.Parsing · 84 unmodified lines | |||
| 586 | buffer = item.Item; | 578 | buffer = item.Item; |
| 587 | 579 | ||
| 588 | // Check to see if this data source has been initialized | 580 | // Check to see if this data source has been initialized |
| 589 | if ((object)m_sourceInitialized != null && !m_sourceInitialized.TryGetValue(m_sourceID, out StreamInitialized)) | 581 | if ((object)m_sourceInitialized != null) |
| 590 | m_sourceInitialized.Add(m_sourceID, true); | 582 | StreamInitialized = m_sourceInitialized.GetOrAdd(m_sourceID, true); |
| 591 | 583 | ||
| 592 | // Restore any unparsed buffers for this data source, if any | 584 | // Restore any unparsed buffers for this data source, if any |
| 593 | lock (m_unparsedBuffers) | 585 | UnparsedBuffer = m_unparsedBuffers.GetOrAdd(m_sourceID, (byte[])null); |
| 594 | { | ||
| 595 | if (!m_unparsedBuffers.TryGetValue(m_sourceID, out UnparsedBuffer)) | ||
| 596 | m_unparsedBuffers.Add(m_sourceID, null); | ||
| 597 | } | ||
| 598 | 586 | ||
| 599 | // Create new collection for parsed output | 587 | // Clear collection to hold new parsed output |
| 600 | m_parsedOutputs = new List<TOutputType>(); | 588 | m_parsedOutputs.Clear(); |
| 601 | 589 | ||
| 602 | // Start parsing sequence for this buffer - this will cumulate new parsed outputs | 590 | // Start parsing sequence for this buffer - this will cumulate new parsed outputs |
| 603 | base.Write(buffer, 0, buffer.Length); | 591 | base.Write(buffer, 0, buffer.Length); |
| 604 | 592 | ||
| 605 | // Track last unparsed buffer for this data source | 593 | // Track last unparsed buffer for this data source |
| 606 | lock (m_unparsedBuffers) | 594 | m_unparsedBuffers[m_sourceID] = UnparsedBuffer; |
| 607 | { | ||
| 608 | m_unparsedBuffers[m_sourceID] = UnparsedBuffer; | ||
| 609 | } | ||
| 610 | 595 | ||
| 611 | // Expose any parsed data | 596 | // Expose any parsed data |
| 612 | if (m_parsedOutputs.Count > 0) | 597 | if (m_parsedOutputs.Count > 0) |
| @@ -626,13 +611,13 @@ namespace GSF.Parsing · 13 unmodified lines | |||
| 626 | } | 611 | } |
| 627 | 612 | ||
| 628 | // Cumulate output data for current data source | 613 | // Cumulate output data for current data source |
| 629 | private void CumulateParsedOutput(object sender, EventArgs<TOutputType> data) | 614 | private void DataParsed_CumulateParsedOutput(object sender, EventArgs<TOutputType> data) |
| 630 | { | 615 | { |
| 631 | m_parsedOutputs.Add(data.Argument); | 616 | m_parsedOutputs.Add(data.Argument); |
| 632 | } | 617 | } |
| 633 | 618 | ||
| 634 | // If an error occurs during parsing from a data source, we reset its initialization state | 619 | // If an error occurs during parsing from a data source, we reset its initialization state |
| 635 | private void ResetDataSourceInitialization(object sender, EventArgs<byte[]> data) | 620 | private void DataDiscarded_ResetDataSourceInitialization(object sender, EventArgs<byte[]> data) |
| 636 | { | 621 | { |
| 637 | if ((object)m_sourceInitialized != null) | 622 | if ((object)m_sourceInitialized != null) |
| 638 | m_sourceInitialized[m_sourceID] = false; | 623 | m_sourceInitialized[m_sourceID] = false; |