<commit_before>﻿namespace Microsoft.HockeyApp
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using Channel;
    using DataContracts;
    using Extensibility;
    using Extensibility.Implementation;
    using Extensibility.Implementation.Platform;
    using Extensibility.Implementation.Tracing;

#if WINRT || WINDOWS_UWP
    using Windows.Foundation.Metadata;
#endif

    /// <summary>
    /// Send events, metrics and other telemetry to the Application Insights service.
    /// </summary>
    internal sealed class TelemetryClient
    {
        private readonly TelemetryConfiguration configuration;
        private readonly IDebugOutput debugOutput;
        private TelemetryContext context;
        private ITelemetryChannel channel;

        /// <summary>
        /// Initializes a new instance of the <see cref="TelemetryClient" /> class. Send telemetry with the active configuration, usually loaded from configuration file.
        /// </summary>
        public TelemetryClient() : this(TelemetryConfiguration.Active)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TelemetryClient" /> class. Send telemetry with the specified <paramref name="configuration"/>.
        /// </summary>
        /// <exception cref="ArgumentNullException">The <paramref name="configuration"/> is null.</exception>
        public TelemetryClient(TelemetryConfiguration configuration)
        {
            if (configuration == null)
            {
                CoreEventSource.Log.TelemetryClientConstructorWithNoTelemetryConfiguration();
                configuration = TelemetryConfiguration.Active;
            }

            this.configuration = configuration;
            this.debugOutput = PlatformSingleton.Current.GetDebugOutput();
        }

        /// <summary>
        /// Gets or sets the current context that will be used to augment telemetry you send.
        /// </summary>
        internal TelemetryContext Context
        {
            get
            {
                // In order to prevent a deadlock, we are calling async method from sync using Task.Run to offload a work to a ThreadPool
                // thread which does not have a SynchronizationContext and there is no real risk for a deadlock.
                // http://stackoverflow.com/questions/28305968/use-task-run-in-synchronous-method-to-avoid-deadlock-waiting-on-async-method
                LazyInitializer.EnsureInitialized(ref this.context, () => { return Task.Run(() => { return this.CreateInitializedContextAsync().Result; }).Result; });
                return this.context;
            }

            set
            {
                this.context = value;
            }
        }

        /// <summary>
        /// Gets or sets the default instrumentation key for all <see cref="ITelemetry"/> objects logged in this <see cref="TelemetryClient"/>.
        /// </summary>
        internal string InstrumentationKey
        {
            get { return this.Context.InstrumentationKey; }
            set { this.Context.InstrumentationKey = value; }
        }

        /// <summary>
        /// Gets or sets the channel used by the client helper. Note that this doesn't need to be public as a customer can create a new client 
        /// with a new channel via telemetry configuration.
        /// </summary>
        internal ITelemetryChannel Channel
        {<commit_msg>Deadlock: use async methods in Task.Run.<commit_after>﻿namespace Microsoft.HockeyApp
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using Channel;
    using DataContracts;
    using Extensibility;
    using Extensibility.Implementation;
    using Extensibility.Implementation.Platform;
    using Extensibility.Implementation.Tracing;

#if WINRT || WINDOWS_UWP
    using Windows.Foundation.Metadata;
#endif

    /// <summary>
    /// Send events, metrics and other telemetry to the Application Insights service.
    /// </summary>
    internal sealed class TelemetryClient
    {
        private readonly TelemetryConfiguration configuration;
        private readonly IDebugOutput debugOutput;
        private TelemetryContext context;
        private ITelemetryChannel channel;

        /// <summary>
        /// Initializes a new instance of the <see cref="TelemetryClient" /> class. Send telemetry with the active configuration, usually loaded from configuration file.
        /// </summary>
        public TelemetryClient() : this(TelemetryConfiguration.Active)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TelemetryClient" /> class. Send telemetry with the specified <paramref name="configuration"/>.
        /// </summary>
        /// <exception cref="ArgumentNullException">The <paramref name="configuration"/> is null.</exception>
        public TelemetryClient(TelemetryConfiguration configuration)
        {
            if (configuration == null)
            {
                CoreEventSource.Log.TelemetryClientConstructorWithNoTelemetryConfiguration();
                configuration = TelemetryConfiguration.Active;
            }

            this.configuration = configuration;
            this.debugOutput = PlatformSingleton.Current.GetDebugOutput();
        }

        /// <summary>
        /// Gets or sets the current context that will be used to augment telemetry you send.
        /// </summary>
        internal TelemetryContext Context
        {
            get
            {
                // In order to prevent a deadlock, we are calling async method from sync using Task.Run to offload a work to a ThreadPool
                // thread which does not have a SynchronizationContext and there is no real risk for a deadlock.
                // http://stackoverflow.com/questions/28305968/use-task-run-in-synchronous-method-to-avoid-deadlock-waiting-on-async-method
                LazyInitializer.EnsureInitialized(ref this.context, () => { return Task.Run(async () => { return await this.CreateInitializedContextAsync(); }).Result; });
                return this.context;
            }

            set
            {
                this.context = value;
            }
        }

        /// <summary>
        /// Gets or sets the default instrumentation key for all <see cref="ITelemetry"/> objects logged in this <see cref="TelemetryClient"/>.
        /// </summary>
        internal string InstrumentationKey
        {
            get { return this.Context.InstrumentationKey; }
            set { this.Context.InstrumentationKey = value; }
        }

        /// <summary>
        /// Gets or sets the channel used by the client helper. Note that this doesn't need to be public as a customer can create a new client 
        /// with a new channel via telemetry configuration.
        /// </summary>
        internal ITelemetryChannel Channel
        {
{'fraction_non_alphanumeric': 0.08628874616029042, 'fraction_numerical': 0.002234012845573862, 'mean_word_length': 2.1878059635068983, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1537285', 'n_tokens_mistral': 1711, 'n_tokens_neox': 1672, 'n_words': 536}