|  | @@ -102,9 +102,10 @@ namespace Emby.Dlna.PlayTo
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  _sessionManager.ReportSessionEnded(_session.Id);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            catch
 | 
	
		
			
				|  |  | +            catch (Exception ex)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  // Could throw if the session is already gone
 | 
	
		
			
				|  |  | +                _logger.LogError(ex, "Error reporting the end of session {Id}", _session.Id);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -112,20 +113,14 @@ namespace Emby.Dlna.PlayTo
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var info = e.Argument;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            info.Headers.TryGetValue("NTS", out string nts);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if (!info.Headers.TryGetValue("USN", out string usn)) usn = string.Empty;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if (!info.Headers.TryGetValue("NT", out string nt)) nt = string.Empty;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if (usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
 | 
	
		
			
				|  |  | -                !_disposed)
 | 
	
		
			
				|  |  | +            if (!_disposed
 | 
	
		
			
				|  |  | +                && info.Headers.TryGetValue("USN", out string usn)
 | 
	
		
			
				|  |  | +                && usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1
 | 
	
		
			
				|  |  | +                && (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1
 | 
	
		
			
				|  |  | +                    || (info.Headers.TryGetValue("NT", out string nt)
 | 
	
		
			
				|  |  | +                        && nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1)))
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1 ||
 | 
	
		
			
				|  |  | -                    nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    OnDeviceUnavailable();
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +                OnDeviceUnavailable();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -612,22 +607,34 @@ namespace Emby.Dlna.PlayTo
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          public void Dispose()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if (!_disposed)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                _disposed = true;
 | 
	
		
			
				|  |  | +            Dispose(true);
 | 
	
		
			
				|  |  | +            GC.SuppressFinalize(this);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                _device.PlaybackStart -= _device_PlaybackStart;
 | 
	
		
			
				|  |  | -                _device.PlaybackProgress -= _device_PlaybackProgress;
 | 
	
		
			
				|  |  | -                _device.PlaybackStopped -= _device_PlaybackStopped;
 | 
	
		
			
				|  |  | -                _device.MediaChanged -= _device_MediaChanged;
 | 
	
		
			
				|  |  | -                //_deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft;
 | 
	
		
			
				|  |  | -                _device.OnDeviceUnavailable = null;
 | 
	
		
			
				|  |  | +        protected virtual void Dispose(bool disposing)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            if (_disposed)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            if (disposing)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  |                  _device.Dispose();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            _device.PlaybackStart -= _device_PlaybackStart;
 | 
	
		
			
				|  |  | +            _device.PlaybackProgress -= _device_PlaybackProgress;
 | 
	
		
			
				|  |  | +            _device.PlaybackStopped -= _device_PlaybackStopped;
 | 
	
		
			
				|  |  | +            _device.MediaChanged -= _device_MediaChanged;
 | 
	
		
			
				|  |  | +            _deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft;
 | 
	
		
			
				|  |  | +            _device.OnDeviceUnavailable = null;
 | 
	
		
			
				|  |  | +            _device = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            _disposed = true;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 | 
	
		
			
				|  |  | +        private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          private Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken)
 | 
	
		
			
				|  |  |          {
 |