I have extended the System.Collections.Concurrent.ConcurrentQueue to raise events as objects are enqueued. I now need to be able to use System.Management.Automation.WriteObject/WriteVerbose/WriteDebug methods to write the objects from the aforementioned events. However, I receive the following error when attempting to use System.Management.Automation.WriteObject/WriteVerbose/WriteDebug in the event handler.
Does anyone know how I can marshal the events back to the main thread so that I can use the System.Management.Automation.WriteObject/WriteVerbose/WriteDebug methods?
Here is my extended ConcurrentQueue class.
public class ConcurrentQueueEx<T> : ConcurrentQueue<T>
{
#region Private Variables
private Guid _id;
#endregion
#region Public Accessors
public Guid Id
{
get { return this._id; }
}
#endregion
#region Event Declarations
public event PSObjectAddedEventHandler PSObjectAdded;
protected virtual void OnPSObjectAdded(Guid parentId, object obj)
{
PSObjectAddedEventHandler handler = PSObjectAdded;
if (handler != null)
{
PSObjectAddedEventArgs oae = new PSObjectAddedEventArgs();
oae._ParentId = parentId;
oae._Object = obj;
handler(oae);
}
}
#endregion
#region Public Functions
public new virtual void Enqueue(T item)
{
base.Enqueue(item);
OnPSObjectAdded(this._id, item);
}
public virtual void Push(T item)
{
base.Enqueue(item);
OnPSObjectAdded(this._id, item);
}
public virtual T Pop()
{
T obj;
base.TryDequeue(out obj);
return obj;
}
#endregion
}
Here are the relevant sections from the cmdlet.
protected override void BeginProcessing()
{
base.BeginProcessing();
_messageQueue = new ConcurrentQueueEx<object>();
_messageQueue.PSObjectAdded += _messageQueue_PSObjectAdded;
_resultQueue = new ConcurrentQueueEx<object>();
_resultQueue.PSObjectAdded += _resultQueue_PSObjectAdded;
}
private void _resultQueue_PSObjectAdded(PSObjectAddedEventArgs e)
{
WriteObject(e._Object);
}
private void _messageQueue_PSObjectAdded(PSObjectAddedEventArgs e)
{
WriteVerbose(e._Object.ToString());
}
Here are the exception details.
System.Management.Automation.PSInvalidOperationException was unhandled by user code
HResult=-2146233079
Message=The WriteObject and WriteError methods cannot be called from outside the overrides of the BeginProcessing, ProcessRecord, and EndProcessing methods, and they can only be called from within the same thread. Validate that the cmdlet makes these calls correctly, or contact Microsoft Customer Support Services.
Source=System.Management.Automation
WriteObject/WriteErrorin an event handler invoked on a thread other than the one on whichBeginProcessing/ProcessRecord/EndProcessingwas called.