Prevent ClipboarService from opening unnecessary handles. Clean up Windows desktop app startup process.

This commit is contained in:
Jared 2020-12-15 16:35:38 -08:00 committed by Jared Goodwin
parent d424d9ff98
commit 2011484e4e
9 changed files with 37 additions and 67 deletions

View File

@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Remotely.Desktop.Win"
DispatcherUnhandledException="Application_DispatcherUnhandledException" Startup="Application_Startup" Exit="Application_Exit">
DispatcherUnhandledException="Application_DispatcherUnhandledException" Startup="Application_Startup">
<Application.Resources>
<Style x:Key="TitlebarButton" TargetType="Button">
<Setter Property="Background" Value="#FF464646"></Setter>

View File

@ -40,16 +40,5 @@ namespace Remotely.Desktop.Win
Environment.Exit(0);
}
}
private void Application_Exit(object sender, ExitEventArgs e)
{
Task.Run(async () =>
{
var casterSocket = ServiceContainer.Instance.GetRequiredService<CasterSocket>();
await casterSocket.DisconnectAllViewers();
System.Windows.Forms.Application.Exit();
Environment.Exit(0);
});
}
}
}

View File

@ -58,7 +58,7 @@ namespace Remotely.Desktop.Win
if (Conductor.Mode == Core.Enums.AppMode.Chat)
{
StartUiThreads(null);
StartUiThreads(false);
await Task.Run(async () =>
{
var chatService = Services.GetRequiredService<IChatHostService>();
@ -67,7 +67,7 @@ namespace Remotely.Desktop.Win
}
else if (Conductor.Mode == Core.Enums.AppMode.Unattended)
{
StartUiThreads(null);
StartUiThreads(false);
App.Current.Dispatcher.Invoke(() =>
{
App.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
@ -76,12 +76,8 @@ namespace Remotely.Desktop.Win
}
else
{
StartUiThreads(() => new MainWindow());
StartUiThreads(true);
}
TaskHelper.DelayUntil(() => App.Current?.Dispatcher?.HasShutdownStarted != false,
TimeSpan.MaxValue,
1000);
}
catch (Exception ex)
{
@ -177,19 +173,20 @@ namespace Remotely.Desktop.Win
Services.GetRequiredService<IClipboardService>().BeginWatching();
}
private static void StartUiThreads(Func<Window> createWindowFunc)
private static void StartUiThreads(bool createMainWindow)
{
var wpfUiThread = new Thread(() =>
{
var app = new App();
app.InitializeComponent();
if (createWindowFunc is null)
if (createMainWindow)
{
app.Run();
app.Run(new MainWindow());
}
else
{
app.Run(createWindowFunc());
app.Run();
}
});
wpfUiThread.TrySetApartmentState(ApartmentState.STA);
@ -202,7 +199,7 @@ namespace Remotely.Desktop.Win
winformsThread.TrySetApartmentState(ApartmentState.STA);
winformsThread.Start();
// Wait until WPF app has initialized before moving on.
while (App.Current is null)
{
Thread.Sleep(100);

View File

@ -26,7 +26,7 @@ namespace Remotely.Desktop.Win.Services
finally
{
cancelTokenSource = new CancellationTokenSource();
_ = Task.Run(() => WatchClipboard(cancelTokenSource.Token));
WatchClipboard(cancelTokenSource.Token);
}
}
@ -51,6 +51,7 @@ namespace Remotely.Desktop.Win.Services
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
return Task.CompletedTask;
@ -68,17 +69,17 @@ namespace Remotely.Desktop.Win.Services
private void WatchClipboard(CancellationToken cancelToken)
{
while (!cancelToken.IsCancellationRequested &&
!Environment.HasShutdownStarted)
var thread = new Thread(() =>
{
var thread = new Thread(() =>
while (!cancelToken.IsCancellationRequested &&
!Environment.HasShutdownStarted)
{
try
{
Win32Interop.SwitchToInputDesktop();
if (Clipboard.ContainsText() && Clipboard.GetText() != ClipboardText)
{
ClipboardText = Clipboard.GetText();
@ -86,11 +87,12 @@ namespace Remotely.Desktop.Win.Services
}
}
catch { }
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
Thread.Sleep(500);
}
Thread.Sleep(500);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
}
}
}

View File

@ -31,6 +31,11 @@ namespace Remotely.Desktop.Win.ViewModels
{
Current = this;
if (Services is null)
{
return;
}
Application.Current.Exit += Application_Exit;
CursorIconWatcher = Services?.GetRequiredService<ICursorIconWatcher>();
@ -185,7 +190,6 @@ namespace Remotely.Desktop.Win.ViewModels
public async Task Init()
{
SessionID = "Retrieving...";
Host = Config.GetConfig().Host;

View File

@ -1,5 +1,6 @@
using Remotely.Desktop.Win.ViewModels;
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@ -56,7 +57,11 @@ namespace Remotely.Desktop.Win.Views
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await ViewModel?.Init();
if (!DesignerProperties.GetIsInDesignMode(this) &&
ViewModel != null)
{
await ViewModel?.Init();
}
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net5.0-windows</TargetFramework>
<AssemblyName>Remotely.Tests.LoadTester</AssemblyName>
<RootNamespace>Remotely.Tests.LoadTester</RootNamespace>
</PropertyGroup>
@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Desktop.Win\Desktop.Win.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>

View File

@ -1,29 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Remotely.Shared.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Remotely.Tests
{
[TestClass]
public class ManaulTests
{
[TestMethod]
//[Ignore("Manual test.")]
public void HandlesCount()
{
var startHandles = Process.GetCurrentProcess().HandleCount;
for (var i = 0; i < 1000; i++)
{
var result = Win32Interop.SwitchToInputDesktop();
}
var endHandles = Process.GetCurrentProcess().HandleCount;
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net5.0-windows</TargetFramework>
<IsPackable>false</IsPackable>
@ -27,6 +27,7 @@
<ItemGroup>
<ProjectReference Include="..\Desktop.Core\Desktop.Core.csproj" />
<ProjectReference Include="..\Desktop.Win\Desktop.Win.csproj" />
<ProjectReference Include="..\Server\Server.csproj" />
</ItemGroup>