/// <summary>
        /// Create a new sample for this metric and populate it with data from the provided user data object.  The caller must write this sample for it to be recorded.
        /// </summary>
        /// <remarks>
        /// The provided user data object must be compatible with the object type used to initialize this event metric.
        /// </remarks>
        /// <param name="userDataObject">The object to retrieve metric values from</param>
        /// <returns>The new metric sample object</returns>
        internal EventMetricSample CreateSample(object userDataObject)
        {
            if (userDataObject == null)
            {
                throw new ArgumentNullException(nameof(userDataObject));
            }

            if (Definition.IsBound == false)
            {
                throw new ArgumentException("This event metric's definition is not bound to sample automatically from a user data object.  CreateSample() and SetValue() must be used to specify the data values directly.");
            }

            Type userDataType = userDataObject.GetType();

            if (Definition.BoundType.IsAssignableFrom(userDataType) == false)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The provided user data object type ({0}) is not assignable to this event metric's bound type ({1}) and can not be sampled automatically for this metric instance.",
                                                          userDataType, Definition.BoundType));
            }

            EventMetricSample metricSample = CreateSample();

            foreach (EventMetricValueDefinition valueDefinition in Definition.ValueCollection)
            {
                if (valueDefinition.Bound == false)
                {
                    continue; // Can't sample values that aren't bound.
                }
                try
                {
                    // Get the numerator value...
                    // ToDo: Change value definition to use NVP (or a new Binding class).
                    NameValuePair <MemberTypes> binding = new NameValuePair <MemberTypes>(valueDefinition.MemberName, valueDefinition.MemberType);
                    BindingFlags dataBindingFlags       = Definition.GetBindingFlags(binding);

                    // This should throw an exception if DataBinding isn't valid, so we'll bail on this column.
                    object rawData = userDataType.InvokeMember(valueDefinition.MemberName, dataBindingFlags, null, userDataObject, null, CultureInfo.InvariantCulture);
                    metricSample.SetValue(valueDefinition, rawData); // This will handle conversion as needed.
                }
                catch
                {
#if DEBUG
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
#endif
                    // We can't write this column if we got an error reading the data.  Write the sample without it?
                }
            }

            return(metricSample);
        }
 public void WriteSample(EventMetricSample metricSample)
 {
     metricSample.Write(); // If it does happen to call, bypassing the error flag, it can forward and work (maybe).
 }
 public static void Write(EventMetricSample metricSample, string str)
 {
     metricSample.Write(); // If it does happen to call, bypassing the error flag, it can forward and work.
 }