private void SendProbe(IPAddress address, int port)
        {
            try
            {
                var uri = new UriBuilder("http", address.ToString(), port);

                var probe = new MTConnectClients.Probe(uri.ToString());
                probe.UserObject = new ProbeSender(address, port);
                probe.Timeout    = Timeout;
                probe.Error     += Probe_Error;

                // Notify that a new Probe request has been sent
                ProbeSent?.Invoke(this, address, port);

                var document = probe.Execute();
                if (document != null)
                {
                    // Get the MAC Address of the sender
                    var macAddress = GetMacAddress(address);

                    foreach (var device in document.Devices)
                    {
                        // Notify that a Device was found
                        DeviceFound?.Invoke(this, new MTConnectDevice(address, port, macAddress, device.Name));
                    }

                    // Notify that the Probe reqeuest was successful
                    ProbeSuccessful?.Invoke(this, address, port);
                }
            }
            catch { }
        }
        private void Worker(object obj)
        {
            long instanceId = -1;
            bool initialize = true;

            do
            {
                var probe = new Probe(BaseUrl, DeviceName);
                probe.Timeout          = Timeout;
                probe.Error           += MTConnectErrorRecieved;
                probe.ConnectionError += ProcessConnectionError;
                var probeDoc = probe.Execute();
                if (probeDoc != null)
                {
                    // Raise ProbeReceived Event
                    ProbeReceived?.Invoke(probeDoc);

                    do
                    {
                        var current = new Current(BaseUrl, DeviceName);
                        current.Timeout          = Timeout;
                        current.Error           += MTConnectErrorRecieved;
                        current.ConnectionError += ProcessConnectionError;
                        var currentDoc = current.Execute();
                        if (currentDoc != null)
                        {
                            // Check if FirstSequence is larger than previously Sampled
                            if (!initialize)
                            {
                                initialize = SampleRange.From > 0 && currentDoc.Header.FirstSequence > SampleRange.From;
                            }

                            if (initialize)
                            {
                                // Raise CurrentReceived Event
                                CurrentReceived?.Invoke(currentDoc);

                                // Check Assets
                                if (currentDoc.DeviceStreams.Count > 0)
                                {
                                    var deviceStream = currentDoc.DeviceStreams.Find(o => o.Name == DeviceName);
                                    if (deviceStream != null && deviceStream.DataItems != null)
                                    {
                                        CheckAssetChanged(deviceStream.DataItems);
                                    }
                                }
                            }

                            // Check if Agent InstanceID has changed (Agent has been reset)
                            if (initialize || instanceId != currentDoc.Header.InstanceId)
                            {
                                SampleRange.Reset();
                                instanceId = currentDoc.Header.InstanceId;

                                // Restart entire request sequence if new Agent Instance Id is read (probe could have changed)
                                if (!initialize)
                                {
                                    break;
                                }
                            }

                            long from;
                            if (initialize)
                            {
                                from = currentDoc.Header.NextSequence;
                            }
                            else
                            {
                                // If recovering from Error then use last Sample Range that was sampled successfully
                                // Try to get Buffer minus 100 (to account for time between current and sample requests)
                                from = currentDoc.Header.LastSequence - (currentDoc.Header.BufferSize - 100);
                                from = Math.Max(from, currentDoc.Header.FirstSequence);
                                from = Math.Max(SampleRange.From, from);
                            }

                            long to;
                            if (initialize)
                            {
                                to = from;
                            }
                            else
                            {
                                // Get up to the MaximumSampleCount
                                to = currentDoc.Header.NextSequence;
                                to = Math.Min(to, from + MaximumSampleCount);
                            }

                            // Set the SampleRange for subsequent samples
                            SampleRange.From = from;
                            SampleRange.To   = to;

                            initialize = false;

                            // Create the Url to use for the Sample Stream
                            string url = CreateSampleUrl(BaseUrl, DeviceName, Interval, from, MaximumSampleCount);

                            // Create and Start the Sample Stream
                            if (sampleStream != null)
                            {
                                sampleStream.Stop();
                            }
                            sampleStream = new Stream(url, "MTConnectStreams");
                            sampleStream.ConnectionTimeout = Timeout;
                            sampleStream.XmlReceived      += ProcessSampleResponse;
                            sampleStream.XmlError         += SampleStream_XmlError;
                            sampleStream.ConnectionError  += ProcessConnectionError;
                            sampleStream.Run();
                        }
                    } while (!stop.WaitOne(RetryInterval, true));
                }
            } while (!stop.WaitOne(RetryInterval, true));

            Stopped?.Invoke();
        }