MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4namespace System.Management.Automation5{6 using System;7 using System.Diagnostics.Eventing;8 using System.Management.Automation.Tracing;9 using System.Threading;10 11 /// <summary>12 /// An object that can be used to execute a method on a threadpool thread while correctly13 /// managing system state, such as flowing ETW activities from the current thread to the14 /// threadpool thread.15 /// </summary>16 public interface IBackgroundDispatcher17 {18 /// <summary>19 /// Works the same as <see cref="ThreadPool.QueueUserWorkItem(WaitCallback)" />, except that it20 /// also manages system state correctly.21 /// </summary>22 bool QueueUserWorkItem(WaitCallback callback);23 24 /// <summary>25 /// Works the same as <see cref="ThreadPool.QueueUserWorkItem(WaitCallback, object)" />, except that it26 /// also manages system state correctly.27 /// </summary>28 bool QueueUserWorkItem(WaitCallback callback, object state);29 30 /// <summary>31 /// Works the same as BeginInvoke would for any other delegate, except that it also manages system state correctly.32 /// </summary>33 IAsyncResult BeginInvoke(WaitCallback callback, object state, AsyncCallback completionCallback, object asyncState);34 35 /// <summary>36 /// Works the same as EndInvoke would for any other delegate, except that it also manages system state correctly.37 /// </summary>38 void EndInvoke(IAsyncResult asyncResult);39 }40 41 /// <summary>42 /// A simple implementation of <see cref="IBackgroundDispatcher" />.43 /// </summary>44 public class BackgroundDispatcher :45 IBackgroundDispatcher46 {47 #region Instance Data48 49 private readonly IMethodInvoker _etwActivityMethodInvoker;50 private readonly WaitCallback _invokerWaitCallback;51 52 #endregion53 54 #region Creation/Cleanup55 56 /// <summary>57 /// Creates a <see cref="BackgroundDispatcher" /> that uses an <see cref="EtwEventCorrelator" />58 /// for activity creation and correlation.59 /// </summary>60 /// <param name="transferProvider">The <see cref="EventProvider" /> to use when logging transfer events61 /// during activity correlation.</param>62 /// <param name="transferEvent">The <see cref="EventDescriptor" /> to use when logging transfer events63 /// during activity correlation.</param>64 public BackgroundDispatcher(EventProvider transferProvider, EventDescriptor transferEvent)65 : this(new EtwActivityReverterMethodInvoker(new EtwEventCorrelator(transferProvider, transferEvent)))66 {67 // nothing68 }69 70 // internal for unit testing only. Otherwise, would be private.71 internal BackgroundDispatcher(IMethodInvoker etwActivityMethodInvoker)72 {73 ArgumentNullException.ThrowIfNull(etwActivityMethodInvoker);74 _etwActivityMethodInvoker = etwActivityMethodInvoker;75 _invokerWaitCallback = DoInvoker;76 }77 78 #endregion79 80 #region Instance Utilities81 82 private void DoInvoker(object invokerArgs)83 {84 var invokerArgsArray = (object[])invokerArgs;85 86 _etwActivityMethodInvoker.Invoker.DynamicInvoke(invokerArgsArray);87 }88 89 #endregion90 91 #region Instance Access92 93 /// <summary>94 /// Implements <see cref="IBackgroundDispatcher.QueueUserWorkItem(WaitCallback)" />.95 /// </summary>96 public bool QueueUserWorkItem(WaitCallback callback)97 {98 return QueueUserWorkItem(callback, null);99 }100 101 /// <summary>102 /// Implements <see cref="IBackgroundDispatcher.QueueUserWorkItem(WaitCallback, object)" />.103 /// </summary>104 public bool QueueUserWorkItem(WaitCallback callback, object state)105 {106 var invokerArgs = _etwActivityMethodInvoker.CreateInvokerArgs(callback, new object[] { state });107 108 var result = ThreadPool.QueueUserWorkItem(_invokerWaitCallback, invokerArgs);109 return result;110 }111 112 /// <summary>113 /// Implements <see cref="IBackgroundDispatcher.BeginInvoke(WaitCallback, object, AsyncCallback, object)" />.114 /// </summary>115 public IAsyncResult BeginInvoke(WaitCallback callback, object state, AsyncCallback completionCallback, object asyncState)116 {117 var invokerArgs = _etwActivityMethodInvoker.CreateInvokerArgs(callback, new object[] { state });118 119 var result = _invokerWaitCallback.BeginInvoke(invokerArgs, completionCallback, asyncState);120 return result;121 }122 123 /// <summary>124 /// Implements <see cref="IBackgroundDispatcher.EndInvoke(IAsyncResult)" />.125 /// </summary>126 public void EndInvoke(IAsyncResult asyncResult)127 {128 _invokerWaitCallback.EndInvoke(asyncResult);129 }130 131 #endregion132 }133}134 