WPF 使用互斥锁Mutex实现应用程序启动唯一实例,避免重复启动

C#中的Mutex是互斥锁,位于命名空间System.Threading中,它是一个互斥的对象,同一时间只有一个线程可以拥有它,该类还可用于进程间同步的同步基元。在系统运行过程中,如果当前有一个线程或者进程拥有它,在没有释放之前,其它线程或进程是没有权利拥有它的,并且使用其构造函数创建对象时设置的name是在系统中唯一的,如:

/*创建具有唯一名称的互斥锁*/
AppMutex = new Mutex(true, "TopToolsApp", out var createdNew);

其中名称“TopToolsApp”在系统中唯一,使用以上的构造函数,可以进行判断当前名称的互斥锁是否可以创建新的,前提是其他线程或进程没有创建该同名的互斥锁,返回参数“createdNew”为false时,表示系统中存在其他线程使用了同名的互斥锁,因此,可以利用这个特性来实现应用程序的唯一启动实例,如:

protected override void OnStartup(StartupEventArgs e)
{
	/*创建具有唯一名称的互斥锁*/
	AppMutex = new Mutex(true, "TopToolsApp", out var createdNew);

	if (!createdNew)
	{
		var current = Process.GetCurrentProcess();

		foreach (var process in Process.GetProcessesByName(current.ProcessName))
		{
			if (process.Id != current.Id)
			{
				Win32Helper.SetForegroundWindow(process.MainWindowHandle);
				break;
			}
		}
		Shutdown();
	}
	else
	{
		//var splashScreen = new SplashScreen("Resources/Img/Cover.png");
		//splashScreen.Show(true);

		base.OnStartup(e);
	}
}

Win32Helper.SetForegroundWindow的具体实现为:

[DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
public static extern void SetForegroundWindow(IntPtr hwnd);

如果需要在程序中使用该互斥锁来实现数据的更新,同时避免同一时刻有其他线程操作,可以使用Mutex.WaitOne()方法等待Mutex对象被释放,如果它等待的Mutex对象被释放了,它就自动拥有这个对象,直到它调用Mutex.ReleaseMutex()方法释放这个对象,而在此期间,其他想要获取这个Mutex对象的线程都只有等待。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用WPF的动画和线程来实现这个功能。以下是一个简单的实现方法: 1. 在启动窗口中,添加一个动画控件,比如一个旋转的圆圈。 2. 启动一个线程,在后台检测连接是否成功。 3. 当连接成功时,关闭启动窗口,打开应用程序主窗口。 以下是一个示例代码: XAML代码: ```xml <Window x:Class="StartupWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:YourNamespace" Title="StartupWindow" Height="300" Width="300"> <Grid> <Canvas> <Ellipse Width="50" Height="50" Fill="Blue"> <Ellipse.RenderTransform> <RotateTransform Angle="0" CenterX="25" CenterY="25"/> </Ellipse.RenderTransform> <Ellipse.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="(Ellipse.RenderTransform).(RotateTransform.Angle)" From="0" To="360" Duration="0:0:1" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Ellipse.Triggers> </Ellipse> </Canvas> </Grid> </Window> ``` C# 代码: ```csharp public partial class StartupWindow : Window { public StartupWindow() { InitializeComponent(); // 启动后台线程 Thread thread = new Thread(new ThreadStart(CheckConnection)); thread.Start(); } private void CheckConnection() { // 检测连接是否成功 bool isConnected = YourNamespace.CheckConnection(); // 如果连接成功,关闭启动窗口,打开主窗口 if (isConnected) { Dispatcher.Invoke(() => { MainWindow mainWindow = new MainWindow(); mainWindow.Show(); Close(); }); } } } ``` 在上面的代码中,我们使用了Canvas和Ellipse来创建一个圆圈动画。我们使用了一个后台线程来检测连接是否成功,如果连接成功,我们使用Dispatcher.Invoke方法在主线程中关闭启动窗口,打开主窗口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值