public static async Task RunSvc(string s_connectionString, String deviceId, string msgOut, ActionReceivedText onRecvdTextD, int devKeepListening=2, int devAutoStart=2, ActionReceivedText oOnStatusUpdate=null, bool keepAlive = false, bool responseExpected = true, DeviceAndSvcCurrentSettings deviceAndSvcCurrentSettings = null )
        {
            if (deviceStream_Svc != null)
            {
                System.Diagnostics.Debug.WriteLine("Svc Socket is already open!");
                return;
            }
            else
            {
                
                try
                {
                    using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString, DeviceStreamingCommon.s_transportType))
                    {
                        if (serviceClient == null)
                        {
                            System.Diagnostics.Debug.WriteLine("Failed to create SericeClient!");
                            //return null;
                        }

                        //Attach keepalive and respond info if set

                        deviceStream_Svc = new DeviceStream_Svc(serviceClient, deviceId, msgOut, onRecvdTextD,  devKeepListening , devAutoStart , oOnStatusUpdate, keepAlive,responseExpected, deviceAndSvcCurrentSettings);
                        if (deviceStream_Svc == null)
                        {
                            System.Diagnostics.Debug.WriteLine("Failed to create DeviceStreamSvc!");
                        }
                        else
                        {
                            try
                            {
                                await deviceStream_Svc.RunSvcAsync();//.GetAwaiter().GetResult();
                            }
                            catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
                            {
                                System.Diagnostics.Debug.WriteLine("3 Error RunSvc(): Hub connection failure");
                            }
                            catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
                            {
                                System.Diagnostics.Debug.WriteLine("3 Error RunSvc(): Device not found");
                            }
                            catch (TaskCanceledException)
                            {
                                System.Diagnostics.Debug.WriteLine("3 Error RunSvc(): Task canceled");
                            }
                            catch (OperationCanceledException)
                            {
                                System.Diagnostics.Debug.WriteLine("3 Error RunSvc(): Operation canceled");
                            }
                            catch (Exception ex)
                            {
                                if (!ex.Message.Contains("Timed out"))
                                    System.Diagnostics.Debug.WriteLine("3 Error RunSvc(): " + ex.Message);
                                else
                                {
                                    System.Diagnostics.Debug.WriteLine("3 Error RunSvc(): Timeout");
                                }
                            }
                        }
                    }
                }
                catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
                {
                    System.Diagnostics.Debug.WriteLine("4 Error RunSvc(): Hub connection failure");
                }
                catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
                {
                    System.Diagnostics.Debug.WriteLine("4 Error RunSvc(): Device not found");
                }
                catch (TaskCanceledException)
                {
                    System.Diagnostics.Debug.WriteLine("4 Error RunSvc(): Task canceled");
                }
                catch (OperationCanceledException)
                {
                    System.Diagnostics.Debug.WriteLine("4 Error RunSvc(): Operation canceled");
                }
                catch (Exception ex)
                {
                    if (!ex.Message.Contains("Timeout"))
                        System.Diagnostics.Debug.WriteLine("4 Error RunSvc(): " + ex.Message);
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("4 Error RunSvc(): Timeout");
                    }
                }
            }
            
        }
        private async Task RunSvcAsync()
        {
            string errorMsg = "";
            string updateMsg = "";
            
            using (cancellationTokenSourceManual = new CancellationTokenSource())
            {
                ClientWebSocket stream = null;
                try
                {
                    DeviceStreamRequest deviceStreamRequest = new DeviceStreamRequest(
                        streamName: "TestStream"
                    );
                    updateMsg = "Starting Svc TestStream";
                    UpdateStatus(updateMsg);

                    cancellationTokenSourceManual.Token.Register(() =>
                    {
                        _serviceClient?.CloseAsync();
                        _serviceClient?.Dispose();
                    });

                    DeviceStreamResponse result = await _serviceClient.CreateStreamAsync(_deviceId, deviceStreamRequest).ConfigureAwait(false);

                    updateMsg = string.Format("Svc Stream response received: Name={0} IsAccepted={1}", deviceStreamRequest.StreamName, result.IsAccepted);
                    UpdateStatus(updateMsg);

                    if (result.IsAccepted)
                    {
                        using (cancellationTokenSourceTimeout = new CancellationTokenSource(DeviceStreamingCommon.DeviceTimeout))
                        {
                            try
                            {
                                using (stream = await DeviceStreamingCommon.GetStreamingClientAsync(result.Url, result.AuthorizationToken, cancellationTokenSourceTimeout.Token).ConfigureAwait(false))
                                {
                                    updateMsg = "Stream is open.";
                                    UpdateStatus(updateMsg);
                                    bool keepAlive = false;
                                    MsgOutWaitHandle = new AutoResetEvent(true);
                                    do
                                    {
                                        //Nb: Not waited on first entry as waiting for msgOut, which we already have.
                                        updateMsg = "Stream is open. Waiting for msg to send.";
                                        UpdateStatus(updateMsg);

                                        MsgOutWaitHandle.WaitOne();
                                        updateMsg = "Sending msg.";
                                        UpdateStatus(updateMsg);
                                        bool caught = false;
                                        try
                                        {
                                          MsgOut = SvcCurrentSettings.ProcessMsgOut(MsgOut, SvcCurrentSettings.KeepAlive, SvcCurrentSettings.ResponseExpected, DevKeepListening , DevAutoStart );
                                        } catch (NotImplementedException )
                                        {
                                            errorMsg += "DeviceCurrentSettings not properly implemented";
                                            keepAlive = false;
                                            caught = true;
                                        }
                                        if (!caught)
                                        {
                                            await SendMsg(stream, MsgOut, cancellationTokenSourceTimeout);
                                            updateMsg = "Sent msg.";
                                            UpdateStatus(updateMsg);

                                            if (this.SvcCurrentSettings.ResponseExpected)
                                            {
                                                byte[] receiveBuffer = new byte[1024];
                                                System.ArraySegment<byte> ReceiveBuffer = new ArraySegment<byte>(receiveBuffer);

                                                var receiveResult = await stream.ReceiveAsync(ReceiveBuffer, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);

                                                MsgIn = Encoding.UTF8.GetString(receiveBuffer, 0, receiveResult.Count);


                                                string subStrn = Azure_IoTHub_DeviceStreaming.DeviceStreamingCommon.DeviceInSimuatedDeviceModeStrn;
                                                int subStrnLen = subStrn.Length;
                                                string subStrn2 = Azure_IoTHub_Sensors.TelemetryDataPoint.Prefix;
                                                int subStrnLen2 = subStrn2.Length;
                                                if (MsgIn.Length>= subStrnLen)
                                                    if (MsgIn.Substring(0,subStrnLen) == subStrn)
                                                {
                                                    MsgIn = MsgIn.Substring(subStrnLen);
                                                    Azure_IoTHub_Telemetry.SyntheticIoTMessage iotHubMessage = Azure_IoTHub_Telemetry.SyntheticIoTMessage.Deserialize(MsgIn);
                                                    Microsoft.Azure.Devices.Client.Message message = iotHubMessage.ToMessage();
                                                    Microsoft.Azure.EventHubs.EventData eventData = Azure_IoTHub_Telemetry.SyntheticIoTMessage.ToEventData(message);
                                                    MsgIn = Azure_IoTHub_Telemetry.SyntheticIoTMessage.EventData_ToString(eventData);
                                                }
                                                
                                                else if (MsgIn.Length >= subStrnLen2)
                                                    if (MsgIn.Substring(0, subStrnLen2) == subStrn2)
                                                    {
                                                        MsgIn = MsgIn.Substring(subStrnLen2);
                                                        Azure_IoTHub_Sensors.TelemetryDataPoint telemetry = Azure_IoTHub_Sensors.TelemetryDataPoint.Deserialize(MsgIn);
                                                        MsgIn = telemetry.ToString();

                                                        //Microsoft.Azure.Devices.Client.Message message = iotHubMessage.ToMessage();
                                                        //Microsoft.Azure.EventHubs.EventData eventData = Azure_IoTHub_Telemetry.SyntheticIoTMessage.ToEventData(message);
                                                        //MsgIn = Azure_IoTHub_Telemetry.SyntheticIoTMessage.EventData_ToString(eventData);
                                                    }
                                                keepAlive = false;
                                                if (SvcCurrentSettings != null)
                                                    keepAlive = this.SvcCurrentSettings.KeepAlive;
                                                try
                                                {
                                                    if (OnRecvdTextD != null)
                                                        OnRecvdTextD(MsgIn);
                                                }
                                                catch (Exception exx)
                                                {
                                                    errorMsg += "OnRecvdTextD not properly implemented: " + exx.Message;
                                                    keepAlive = false;
                                                }

                                                updateMsg = string.Format("Svc Received stream data: {0}", MsgIn);
                                                UpdateStatus(updateMsg);
                                            }
                                            MsgOutWaitHandle.Reset();
                                        }
                                    } while (keepAlive) ;
                                    MsgOutWaitHandle = null;
                                    updateMsg = "Closing Svc Socket";
                                    UpdateStatus(updateMsg);
                                    await stream.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationTokenSourceTimeout.Token).ConfigureAwait(false);
                                    stream = null;
                                }
                            }
                            catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Hub connection failure");
                                errorMsg = "Hub connection failure";
                            }
                            catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Device not found");
                                errorMsg = "Device not found";
                            }
                            catch (TaskCanceledException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Task cancelled");
                                errorMsg = "Task cancelled";
                            }
                            catch (OperationCanceledException)
                            {
                                System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Operation cancelled");
                                errorMsg = "Operation cancelled";
                            }
                            catch (Exception ex)
                            {
                                if ((bool)cancellationTokenSourceManual?.IsCancellationRequested)
                                {
                                    System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Cancelled.");
                                    errorMsg = "Cancelled";
                                }
                                else if ((bool)cancellationTokenSourceTimeout?.IsCancellationRequested)
                                {
                                    System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): Timed Out.");
                                    errorMsg = "Timed Out";
                                }
                                else if (!ex.Message.Contains("Timed out"))
                                {
                                    System.Diagnostics.Debug.WriteLine("1 Error RunSvcAsync(): " + ex.Message);
                                    errorMsg = ex.Message;
                                }
                                else
                                {
                                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Timed out");
                                    errorMsg = "Timed Out";
                                }
                            }
                        }
                    }
                }
                catch (Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Hub connection failure");
                    errorMsg += " Hub connection failure";
                }
                catch (Microsoft.Azure.Devices.Common.Exceptions.DeviceNotFoundException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Device not found");
                    errorMsg += " Device not found";
                }
                catch (TaskCanceledException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Task cancelled");
                    errorMsg += " Task cancelled";
                }
                catch (OperationCanceledException)
                {
                    System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Operation cancelled");
                    errorMsg += " Operation cancelled";
                }
                catch (Exception ex)
                { if ((bool)cancellationTokenSourceManual?.IsCancellationRequested)
                    {
                        System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Cancelled.");
                        errorMsg += " Cancelled";
                    }
                    else if ((bool)cancellationTokenSourceTimeout?.IsCancellationRequested)
                    {
                        System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Timed Out.");
                        errorMsg += " Timed Out";
                    }
                    else if (!ex.Message.Contains("Timed out"))
                    {
                        System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): " + ex.Message);
                        errorMsg += " " + ex.Message;
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("2 Error RunSvcAsync(): Timed out");
                        errorMsg += " Timed Out";
                    }
                };

                if (stream != null)
                {
                    if (stream.CloseStatus != WebSocketCloseStatus.NormalClosure)
                    {
                        updateMsg= "Aborting Svc Socket as is errant or cancelled: " + errorMsg;
                        UpdateStatus(updateMsg);
                        stream.Abort();
                        updateMsg = "Aborted Svc Socket as was errant or cancelled:" + errorMsg;
                        UpdateStatus(updateMsg);
                    }
                    else
                    {
                        updateMsg = "Socket closed normally: " + errorMsg;
                        UpdateStatus(updateMsg);
                    }
                    stream = null;
                }
                else
                {
                    updateMsg = "Socket closed Normally: " + errorMsg; 
                    UpdateStatus(updateMsg);
                }

                deviceStream_Svc = null;
                MsgOutWaitHandle = null;
                cancellationTokenSourceTimeout = null;
            }
        }