public void InitializeIOdeviceInIndividualThread(IOutputDevice outputDevice) { Task.Factory.StartNew(() => { Thread.CurrentThread.Name = $"{outputDevice} Output Thread"; IReinitializeable reinitOutputDevice = outputDevice as IReinitializeable; bool locked = false; try { if (!outputDevice.IsInitialized) { if (outputDevice.IsLockingRequiredForInitialize()) { IOmonitor.IdleForLock(outputDevice, out locked); } outputDevice.Initialize(this); } else if (reinitOutputDevice != null) { if (outputDevice.IsLockingRequiredForInitialize() || outputDevice.IsLockingRequiredForDispose()) { IOmonitor.IdleForLock(outputDevice, out locked); } reinitOutputDevice.Reinitialize(this, true); } else { return; } } finally { if (locked) { IOmonitor.Unlock(outputDevice); } } IOmonitor.IdleWhile(() => outputDevice.IsInitialized); }); }
public virtual void Output(byte[] outData) { try { IOmonitor.IdleForLock(_IOprocessing); // byte[] outdevData; switch (_OutputConverting) { case OutputConvertings.String: outdevData = Encoding.Convert(ParentIDE.Machine.CharSet, _OutputDevice.CharSet , outData); break; case OutputConvertings.ParsingNumber: outdevData = XBinary.ConvertBinaryNumberBytesToTextNumberBytes(outData , ParentIDE.Machine.ByteOrder, _OutputDevice.CharSet); Array.Resize <byte>(ref outdevData, outdevData.Length + _bOutSeparator.Length); Array.Copy(_bOutSeparator, 0, outdevData, outdevData.Length - _bOutSeparator.Length, _bOutSeparator.Length); break; case OutputConvertings.None: outdevData = outData; break; default: throw new Exception(); } bool outDone, locked; if (!OutputAsyncAllowed) { locked = false; if ((OutputDeviceThreadSafe.Initialize & _OutputDeviceIsThreadSafeFor) == 0) { IOmonitor.IdleForLock(_OutputDevice, out locked); if (!_OutputDevice.IsInitialized) { _OutputDevice.Initialize(this); } } else if (!_OutputDevice.IsInitialized) { _OutputDevice.Initialize(this); } if (!locked && (OutputDeviceThreadSafe.Output & _OutputDeviceIsThreadSafeFor) == 0) { IOmonitor.IdleForLock(_OutputDevice, out locked); } if (_bOutputForeword != null) { _OutputDevice.Output(this, _bOutputForeword); } _OutputDevice.Output(this, outdevData); if (_bOutputAfterword != null) { _OutputDevice.Output(this, _bOutputAfterword); } if (locked) { IOmonitor.Unlock(_OutputDevice); } } else // using output buffer: { if (_BackgroundOutputTask == null) // I. if buffer is empty { locked = false; if ((OutputDeviceThreadSafe.Initialize & _OutputDeviceIsThreadSafeFor) == 0) { IOmonitor.TryLock(_OutputDevice, out locked); if (locked && !_OutputDevice.IsInitialized) { _OutputDevice.Initialize(this); } } else if (!_OutputDevice.IsInitialized) { _OutputDevice.Initialize(this); } // try instant output synchronously outDone = false; if ((OutputDeviceThreadSafe.Output & _OutputDeviceIsThreadSafeFor) == 0) { if (locked || IOmonitor.TryLock(_OutputDevice)) { if (_OutputDevice.IsReadyToOutput) { if (_bOutputForeword != null) { _OutputDevice.Output(this, _bOutputForeword); } _OutputDevice.Output(this, outdevData); if (_bOutputAfterword != null) { _OutputDevice.Output(this, _bOutputAfterword); } outDone = true; } IOmonitor.Unlock(_OutputDevice); } } else if (_OutputDevice.IsReadyToOutput) { if (_bOutputForeword != null) { _OutputDevice.Output(this, _bOutputForeword); } _OutputDevice.Output(this, outdevData); if (_bOutputAfterword != null) { _OutputDevice.Output(this, _bOutputAfterword); } outDone = true; } // if sync output didn't occure, starting async task for outputting buffer if (!outDone) { lock (_OutputBuffer) { _OutputBuffer.AddRange(outdevData); _BackgroundOutputTask = Task.Run(_BackgroundOutputAction); } } } else // II. if buffer is not empty { // initializing output device if it needs to if ((OutputDeviceThreadSafe.Initialize & _OutputDeviceIsThreadSafeFor) == 0) { if (IOmonitor.TryLock(_OutputDevice)) { if (!_OutputDevice.IsInitialized) { _OutputDevice.Initialize(this); } IOmonitor.Unlock(_OutputDevice); } } else if (!_OutputDevice.IsInitialized) { _OutputDevice.Initialize(this); } // populating buffer lock (_OutputBuffer) _OutputBuffer.AddRange(outdevData); } } } finally { IOmonitor.Unlock(_OutputDevice); // IOmonitor.Unlock(_IOprocessing); } }