From 03959e785f635697fcdf0f99aad9454fafbf4e2e Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Thu, 14 Jun 2018 11:57:22 +0300 Subject: Improved UdpDiscoveryClient (I Think...). Improved PPC NavigationManager by providing a way to navigate by module/view paths.. --- .../Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj | 8 ++ .../PPC/Modules/Tango.PPC.Jobs/ViewModelLocator.cs | 14 ++- .../Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs | 17 +++ .../PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml | 14 +++ .../Modules/Tango.PPC.Jobs/Views/JobView.xaml.cs | 28 +++++ .../PPC/Modules/Tango.PPC.Jobs/Views/MainView.xaml | 6 +- .../Navigation/INavigationManager.cs | 21 ++++ .../Tango.PPC.Common/Navigation/NavigationView.cs | 3 +- .../Navigation/DefaultNavigationManager.cs | 62 ++++++++-- .../PPCApplication/DefaultPPCApplicationManager.cs | 1 + .../PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs | 8 +- .../PPC/Tango.PPC.UI/Views/LayoutView.xaml | 2 +- .../PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs | 5 - .../PPC/Tango.PPC.UI/Views/MainView.xaml | 6 +- .../ExtensionMethods/DependencyObjectExtensions.cs | 2 + .../ExtensionMethods/FrameworkElementExtensions.cs | 133 +++++++++++++++++++++ .../Tango.SharedUI/Controls/NavigationControl.cs | 21 +++- .../ExtensionMethods/FrameworkElementExtensions.cs | 13 ++ .../Discovery/UdpDiscoveryClient.cs | 72 ++++++----- 19 files changed, 380 insertions(+), 56 deletions(-) create mode 100644 Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml create mode 100644 Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml.cs (limited to 'Software/Visual_Studio') diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj index 48826d1f4..0f5a698d0 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj @@ -72,6 +72,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -96,11 +100,15 @@ True + JobsView.xaml + + JobView.xaml + MainView.xaml diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModelLocator.cs index e9f636b80..171c35846 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModelLocator.cs @@ -17,6 +17,7 @@ namespace Tango.PPC.Jobs { TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); } /// @@ -31,7 +32,7 @@ namespace Tango.PPC.Jobs } /// - /// Gets the main view VM. + /// Gets the jobs list VM. /// public static JobsViewVM JobsViewVM { @@ -40,5 +41,16 @@ namespace Tango.PPC.Jobs return TangoIOC.Default.GetInstance(); } } + + /// + /// Gets the job details VM. + /// + public static JobViewVM JobViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } } } diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs new file mode 100644 index 000000000..55c5850f2 --- /dev/null +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common; + +namespace Tango.PPC.Jobs.ViewModels +{ + public class JobViewVM : PPCViewModel + { + public override void OnApplicationStarted() + { + + } + } +} diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml new file mode 100644 index 000000000..993b2365a --- /dev/null +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml @@ -0,0 +1,14 @@ + + + + + diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml.cs new file mode 100644 index 000000000..c3e3ab688 --- /dev/null +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.Jobs.Views +{ + /// + /// Interaction logic for JobView.xaml + /// + public partial class JobView : UserControl + { + public JobView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/MainView.xaml b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/MainView.xaml index 4c9f432cb..6b62bcc30 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/MainView.xaml +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/MainView.xaml @@ -7,9 +7,13 @@ xmlns:views="clr-namespace:Tango.PPC.Jobs.Views" xmlns:global="clr-namespace:Tango.PPC.Jobs" xmlns:local="clr-namespace:Tango.PPC.Jobs.Views" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/INavigationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/INavigationManager.cs index 60ca12530..c0f7265fb 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/INavigationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/INavigationManager.cs @@ -22,5 +22,26 @@ namespace Tango.PPC.Common.Navigation /// /// void NavigateTo() where T : IPPCModule; + + /// + /// Navigates to the specified module using the view path (e.g MainView.JobsView). + /// + /// + /// The view path. + void NavigateTo(String viewPath) where T : IPPCModule; + + /// + /// Navigates to the specified module using the view path (e.g MainView,JobsView). + /// This method makes it easy to do stuff like NavigateTo(nameof(MainView),nameof(JobsView)); + /// + /// + /// The view path. + void NavigateTo(params String[] viewPath) where T : IPPCModule; + + /// + /// Navigates to the specified module name. + /// + /// Name of the module. + void NavigateTo(String moduleName); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs index d860bce76..457aaf0ab 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs @@ -13,6 +13,7 @@ namespace Tango.PPC.Common.Navigation { LoadingView, LayoutView, - JobsView, + HomeModule, + ShutdownView, } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs index 12c759c1a..8c42a3a44 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs @@ -3,7 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; using Tango.PPC.Common; +using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; using Tango.PPC.UI.Views; using Tango.SharedUI.Controls; @@ -12,23 +15,68 @@ namespace Tango.PPC.UI.Navigation { public class DefaultNavigationManager : INavigationManager { + private IPPCModuleLoader _moduleLoader; + + public DefaultNavigationManager(IPPCModuleLoader moduleLoader) + { + _moduleLoader = moduleLoader; + } + public void NavigateTo(NavigationView view) { - NavigationControl[] controls = new NavigationControl[] + if (view == NavigationView.HomeModule) { - MainView.Instance.NavigationControl, - LayoutView.Instance.NavigationControl - }; - - var control = controls.Where(x => x.Elements.ToList().Exists(y => NavigationControl.GetNavigationName(y) == view.ToString())).SingleOrDefault(); - control.NavigateTo(view.ToString()); + MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); + var firstModule = _moduleLoader.UserModules.FirstOrDefault(); + LayoutView.Instance.NavigationControl.NavigateTo(firstModule.Name); + } + else + { + MainView.Instance.NavigationControl.NavigateTo(view.ToString()); + } } public void NavigateTo() where T : IPPCModule { + MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); var navigationControl = LayoutView.Instance.NavigationControl; + var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType() == typeof(T)); + navigationControl.NavigateTo(module.Name); + } + public void NavigateTo(string viewPath) where T : IPPCModule + { + NavigateTo(viewPath.Split(',')); + } + public void NavigateTo(params String[] viewPath) where T : IPPCModule + { + MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); + var navigationControl = LayoutView.Instance.NavigationControl; + var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType() == typeof(T)); + var moduleView = navigationControl.NavigateTo(module.Name); + + var moduleNavigation = moduleView.FindChildOffline(); + + foreach (var view in viewPath) + { + moduleNavigation.RegisterForLoadedOrNow(async (x, e) => + { + await Task.Delay(100); + var v = moduleNavigation.NavigateTo(view); + + if (view != viewPath.Last()) + { + moduleNavigation = v.FindChildOffline(); + } + }); + } + } + + public void NavigateTo(string moduleName) + { + var navigationControl = LayoutView.Instance.NavigationControl; + navigationControl.NavigateTo(moduleName); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs index 8b772b8bc..2fbc6c34e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -15,6 +15,7 @@ using Tango.Core; using System.IO; using Tango.Core.Helpers; using Tango.PPC.Common.Modules; +using System.Windows.Threading; namespace Tango.PPC.UI.PPCApplication { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs index 20752ac71..588cc8b64 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs @@ -6,18 +6,24 @@ using System.Text; using System.Threading.Tasks; using Tango.BL; using Tango.Core; +using Tango.Core.DI; using Tango.Core.Helpers; using Tango.PPC.Common; using Tango.PPC.Common.Application; using Tango.PPC.Common.Authentication; +using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; using Tango.PPC.Common.Notifications; +using Tango.PPC.Jobs; using Tango.SharedUI; namespace Tango.PPC.UI.ViewModels { public class LoadingViewVM : PPCViewModel { + [TangoInject] + public IPPCModuleLoader ModuleLoader { get; set; } + public async override void OnApplicationStarted() { await Task.Factory.StartNew(() => @@ -27,7 +33,7 @@ namespace Tango.PPC.UI.ViewModels ApplicationManager.ModulesInitialized += (_, __) => { - NavigationManager.NavigateTo(NavigationView.LayoutView); + NavigationManager.NavigateTo(NavigationView.HomeModule); }; await AuthenticationProvider.Login("roy@twine-s.com", "1234"); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml index 46e104627..8baeab6a4 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml @@ -97,7 +97,7 @@ - + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs index 8ab602f2c..18ffa8ab2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs @@ -46,11 +46,6 @@ namespace Tango.PPC.UI.Views module.Initialize(); } } - - if (modules.Count() > 0) - { - NavigationControl.NavigateTo(modules.First().Name); - } }); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml index 8da05f0dd..1bfdda517 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml @@ -11,9 +11,9 @@ mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - - - + + + diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs index a12ca4f7f..12eba6bb3 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media; using System.Windows.Media.Animation; diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/FrameworkElementExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/FrameworkElementExtensions.cs index 216f6ae0c..2193127cf 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/FrameworkElementExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/FrameworkElementExtensions.cs @@ -1,11 +1,14 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; +using System.Windows.Markup; using Tango.Core.EventArguments; public static class FrameworkElementExtensions @@ -309,5 +312,135 @@ public static class FrameworkElementExtensions #endregion + #region Loaded + /// + /// Registers for the element loaded event. if the element is already loaded will invoke the handler immediately. + /// + /// The element. + /// The handler. + public static void RegisterForLoadedOrNow(this FrameworkElement element, EventHandler handler) + { + if (element.IsLoaded) + { + handler(element, new EventArgs()); + } + else + { + bool isLoaded = false; + + element.Loaded += (sender, e) => + { + if (!isLoaded) + { + isLoaded = true; + + handler(element, new EventArgs()); + } + }; + } + } + + #endregion + + /// + /// A recursive search for a child of type T in memory and not on logical/visual tree. + /// + /// + /// The element. + /// + public static T FindChildOffline(this FrameworkElement element) where T : DependencyObject + { + if (element == null) return null; + + PropertyInfo contentProp = element.GetType().GetProperty("Child"); + + if (contentProp == null) + { + contentProp = element.GetType().GetProperty("Content"); + } + + if (contentProp != null) + { + var value = contentProp.GetValue(element); + + if (value != null) + { + if (value.GetType() == typeof(T)) + { + return (T)value; + } + else + { + return FindChildOffline(value as FrameworkElement); + } + } + } + + if (element is Panel) + { + foreach (var child in (element as Panel).Children.OfType()) + { + if (child.GetType() == typeof(T)) + { + return child as T; + } + else + { + var result = FindChildOffline(child); + + if (result != null) + { + return result; + } + } + } + } + + var contentAtt = element.GetType().GetCustomAttribute(); + + if (contentAtt != null) + { + contentProp = element.GetType().GetProperty(contentAtt.Name); + + if (contentProp != null) + { + var content = contentProp.GetValue(element); + + if (content != null) + { + if (content is IEnumerable) + { + foreach (var child in (content as IEnumerable)) + { + if (child.GetType() == typeof(T)) + { + return child as T; + } + else + { + var result = FindChildOffline(child as FrameworkElement); + + if (result != null) + { + return result; + } + } + } + } + else + { + var result = FindChildOffline(content as FrameworkElement); + + if (result != null) + { + return result; + } + } + } + } + } + + return null; + } } diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs index 5a39948b2..72e7e50c8 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs @@ -9,6 +9,7 @@ using System.Windows.Controls; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Animation; +using System.Windows.Threading; using Tango.SharedUI.Helpers; namespace Tango.SharedUI.Controls @@ -228,7 +229,7 @@ namespace Tango.SharedUI.Controls /// public static String GetNavigationName(FrameworkElement element) { - return element.GetValue(NavigationName).ToString(); + return element.GetValue(NavigationName).ToStringSafe(); } #endregion @@ -438,12 +439,24 @@ namespace Tango.SharedUI.Controls public void NavigateTo(FrameworkElement element) { - SelectedElement = element; + var e = Elements.SingleOrDefault(x => x == element); + + if (e != null) + { + SelectedElement = element; + } } - public void NavigateTo(String navigationName) + public FrameworkElement NavigateTo(String navigationName) { - SelectedElement = Elements.SingleOrDefault(x => GetNavigationName(x) == navigationName); + var element = Elements.SingleOrDefault(x => GetNavigationName(x) == navigationName || x.GetType().Name == navigationName); + + if (element != null) + { + SelectedElement = element; + } + + return element; } public FrameworkElement GetAndDetach(String navigationName) diff --git a/Software/Visual_Studio/Tango.SharedUI/ExtensionMethods/FrameworkElementExtensions.cs b/Software/Visual_Studio/Tango.SharedUI/ExtensionMethods/FrameworkElementExtensions.cs index 422b078a4..8bfc9149a 100644 --- a/Software/Visual_Studio/Tango.SharedUI/ExtensionMethods/FrameworkElementExtensions.cs +++ b/Software/Visual_Studio/Tango.SharedUI/ExtensionMethods/FrameworkElementExtensions.cs @@ -1,15 +1,28 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Drawing.Imaging; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; +using System.Windows.Markup; using System.Windows.Media.Imaging; +using Tango.SharedUI.Controls; using Tango.SharedUI.Rendering; public static class FrameworkElementExtensions { + /// + /// Renders the element to bitmap file. + /// + /// The element. + /// The file path. + /// The format. + /// Size of the render. + /// The quality. public static void RenderToFile(this FrameworkElement element, String filePath, ImageFormat format, Size renderSize, int quality) { RenderWindow renderer = new RenderWindow(element); diff --git a/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryClient.cs b/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryClient.cs index ee3f4cc58..9d043023b 100644 --- a/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryClient.cs +++ b/Software/Visual_Studio/Tango.Transport/Discovery/UdpDiscoveryClient.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Timers; using Tango.PMR.Discovery; @@ -13,7 +14,7 @@ namespace Tango.Transport.Discovery { public class UdpDiscoveryClient : IDiscoveryClient where DiscoveryMessage : IMessage { - private Timer _timer; + private Thread _receiveThread; /// /// Occurs when a matching service has been discovered. @@ -59,13 +60,11 @@ namespace Tango.Transport.Discovery { if (!IsStarted) { - _timer = new Timer(); - _timer.Interval = 10; - _timer.Elapsed += _timer_Elapsed; - _timer.Enabled = true; - _timer.Start(); - IsStarted = true; + + _receiveThread = new Thread(ReceiveThreadLoop); + _receiveThread.IsBackground = true; + _receiveThread.Start(); } } @@ -76,7 +75,6 @@ namespace Tango.Transport.Discovery { if (IsStarted) { - _timer.Stop(); IsStarted = false; } } @@ -86,41 +84,51 @@ namespace Tango.Transport.Discovery /// /// The source of the event. /// The instance containing the event data. - private void _timer_Elapsed(object sender, ElapsedEventArgs e) + private void ReceiveThreadLoop() { - _timer.Interval = Interval.TotalMilliseconds; - - if (!IsStarted) return; - UdpClient udpClient = new UdpClient(Port); - udpClient.Client.ReceiveTimeout = (int)_timer.Interval; + udpClient.Client.ReceiveTimeout = (int)Interval.TotalMilliseconds; var endPoint = new IPEndPoint(IPAddress.Any, 0); - try + while (IsStarted) { - var data = udpClient.Receive(ref endPoint); - udpClient.Close(); + try + { + byte[] data = null; - if (!IsStarted) return; + do + { + data = udpClient.Receive(ref endPoint); - DiscoveryMessage message = Activator.CreateInstance(); - var parser = message.GetParser(); + if (IsStarted) + { + if (data != null && data.Length > 0) + { + DiscoveryMessage message = Activator.CreateInstance(); + var parser = message.GetParser(); - message = (DiscoveryMessage)parser.ParseFrom(data); + message = (DiscoveryMessage)parser.ParseFrom(data); - var host = Dns.GetHostEntry(endPoint.Address); + var host = Dns.GetHostEntry(endPoint.Address); - ServiceDiscovered?.Invoke(this, - new DiscoveredService( - endPoint.Address.ToString(), - host != null ? host.HostName : "Unresolved", - message)); - } - catch { } - finally - { - udpClient.Close(); + ServiceDiscovered?.Invoke(this, + new DiscoveredService( + endPoint.Address.ToString(), + host != null ? host.HostName : "Unresolved", + message)); + } + } + + } while (IsStarted && data != null && data.Length > 0); + } + catch { } + + if (!IsStarted) break; + + Thread.Sleep(Interval); } + + udpClient.Close(); } /// -- cgit v1.3.1