예제 #1
0
        private static void UpdateAssemblyWatchers()
        {
            string[] assemblyPaths = SharedRuntimeState.GetHotReloadAssemblyPaths();
            if (assemblyPaths != null)
            {
                HashSet <string> newAssemblyPaths     = new HashSet <string>();
                HashSet <string> removedAssemblyPaths = new HashSet <string>();

                foreach (string assemblyPath in assemblyWatchers.Keys)
                {
                    if (!assemblyPaths.Contains(assemblyPath))
                    {
                        removedAssemblyPaths.Add(assemblyPath);
                    }
                }

                foreach (string assemblyPath in assemblyPaths)
                {
                    if (!assemblyWatchers.ContainsKey(assemblyPath))
                    {
                        newAssemblyPaths.Add(assemblyPath);
                    }
                }

                foreach (string assemblyPath in removedAssemblyPaths)
                {
                    assemblyWatchers[assemblyPath].Dispose();
                    assemblyWatchers.Remove(assemblyPath);
                }

                foreach (string assemblyPath in newAssemblyPaths)
                {
                    if (Directory.Exists(Path.GetDirectoryName(assemblyPath)))
                    {
                        FileSystemWatcher assemblyWatcher = new FileSystemWatcher();
                        assemblyWatcher.Path                = Path.GetDirectoryName(assemblyPath);
                        assemblyWatcher.Filter              = Path.GetFileName(assemblyPath);
                        assemblyWatcher.NotifyFilter        = NotifyFilters.LastWrite;//NotifyFilters.CreationTime;
                        assemblyWatcher.EnableRaisingEvents = true;
                        assemblyWatcher.Changed            += AssemblyWatcher_Changed;

                        assemblyWatchers.Add(assemblyPath, assemblyWatcher);
                    }
                }
            }

            if (assemblyWatchers.Count == 0)
            {
                SharedRuntimeState.LogWarning("No assembly watchers active for hotreload (\"USharpRuntime reload\" command can be used instead)");
            }
        }
예제 #2
0
        private static void AssemblyWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            if (!SharedRuntimeState.IsActiveRuntime)
            {
                return;
            }

            lock (assemblyWatchers)
            {
                // Require 500 milliseconds between updates to avoid multiple reloads
                //
                // Note: This may result in a genuine change to be missed which means
                // that some user action will be needed
                //
                // PossibleFix: Make this delayed and only catch the latest one? (will slow
                // reloads based on delay interval)
                if (lastAssemblyUpdate < DateTime.Now - TimeSpan.FromMilliseconds(500) && !isAssemblyWatcherReloading)
                {
                    bool complete = false;
                    bool hasChanged = false;

                    const int tries = 20;
                    const int sleep = 40;// 40*20 = 800 milliseconds of attempts (due to file locks whilst being written by AssemblyRewriter)
                    for (int i = 0; i < tries; i++)
                    {
                        try
                        {
                            if (File.Exists(e.FullPath))
                            {
                                using (FileStream reader = File.Open(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                                {
                                    if (reader.Length > 8)
                                    {
                                        reader.Position = reader.Length - 8;
                                        byte[] buffer = new byte[8];
                                        reader.Read(buffer, 0, buffer.Length);
                                        long signature = BitConverter.ToInt64(buffer, 0);
                                        if (signature == 3110675979262317867)// "+UEsRW++"
                                        {
                                            hasChanged = true;
                                        }
                                    }
                                }
                            }
                            complete = true;
                            break;
                        }
                        catch (IOException)
                        {
                            Thread.Sleep(sleep);
                        }
                        catch (Exception exception)
                        {
                            // Some unknown exception
                            SharedRuntimeState.LogWarning("Exception whilst hotreloading '" + e.FullPath + "'\n" + exception);
                            complete = true;
                            break;
                        }
                    }

                    if (hasChanged)
                    {
                        isAssemblyWatcherReloading = true;
                        ReloadMainContext();
                        lastAssemblyUpdate = DateTime.Now;
                        isAssemblyWatcherReloading = false;
                    }
                    else if (!complete)
                    {
                        SharedRuntimeState.LogWarning("Hotreload timed out for '" + e.FullPath + "'");
                    }
                }
            }
        }
예제 #3
0
        private static void UpdateAssemblyWatchers()
        {
            string platformName = SharedRuntimeState.GetPlatformName();
            if (SharedRuntimeState.CurrentRuntime == EDotNetRuntime.Mono &&
                !string.IsNullOrEmpty(platformName) && platformName.ToLower() == "mac")
            {
                // libmono-native-compat.dylib (required by FileSystemWatcher) either doesn't load or is corrupted?
                // It crashes the Mono runtime when doing a symbol lookup (not sure which symbol)
                //
                // abort_with_payload
                // dyld::fastBindLazySymbol(ImageLoader**, unsigned long)
                // dyld_stub_binder
                // ---- managed frames  ----
                // mono_jit_runtime_invoke
                return;
            }

            string[] assemblyPaths = SharedRuntimeState.GetHotReloadAssemblyPaths();
            if (assemblyPaths != null)
            {
                HashSet<string> newAssemblyPaths = new HashSet<string>();
                HashSet<string> removedAssemblyPaths = new HashSet<string>();

                foreach (string assemblyPath in assemblyWatchers.Keys)
                {
                    if (!assemblyPaths.Contains(assemblyPath))
                    {
                        removedAssemblyPaths.Add(assemblyPath);
                    }
                }

                foreach (string assemblyPath in assemblyPaths)
                {
                    if (!assemblyWatchers.ContainsKey(assemblyPath))
                    {
                        newAssemblyPaths.Add(assemblyPath);
                    }
                }

                foreach (string assemblyPath in removedAssemblyPaths)
                {
                    assemblyWatchers[assemblyPath].Dispose();
                    assemblyWatchers.Remove(assemblyPath);
                }

                foreach (string assemblyPath in newAssemblyPaths)
                {
                    if (Directory.Exists(Path.GetDirectoryName(assemblyPath)))
                    {
                        FileSystemWatcher assemblyWatcher = new FileSystemWatcher();
                        assemblyWatcher.Path = Path.GetDirectoryName(assemblyPath);
                        assemblyWatcher.Filter = Path.GetFileName(assemblyPath);
                        assemblyWatcher.NotifyFilter = NotifyFilters.LastWrite;//NotifyFilters.CreationTime;
                        assemblyWatcher.EnableRaisingEvents = true;
                        assemblyWatcher.Changed += AssemblyWatcher_Changed;

                        assemblyWatchers.Add(assemblyPath, assemblyWatcher);
                    }
                }
            }

            if (assemblyWatchers.Count == 0)
            {
                SharedRuntimeState.LogWarning("No assembly watchers active for hotreload (\"USharpRuntime reload\" command can be used instead)");
            }
        }