実現したいこと
WinUI3でUIを、Pythonで主な処理を行うアプリを考えています。
WinUI3からPythonを呼んで処理をさせることはできましたが、
Appを終了(ウインドウの✕ボタン押下)してもタスクが残ってしまいます。
どの様な問題が考えられますか?また、どのように対処すべきでしょうか?
環境
・Visual Studio 2022
・WinUI3
・.Net 6
・NuGet にて Pythonnet v3.0.1 をインストール
・プロジェクトフォルダにpythondllフォルダを作成し、python39.dll を保存
発生している問題・エラーメッセージ
メインウインドウ上にボタンを設置し、そのボタンをクリックすると、Python で sinの値を計算し、ボタンのTextをその値に書き換えるとというAppとなっています。
Click Me をクリックすると、次の様に、Sin0を計算してその結果をボタンのTextに書き込んでいます。
ここまでは想定通りです。
次に、Appを終了するために✕ボタンを押下したところ、ウインドウは消えるが、タスクは残ってしまいます。
タスクマネージャーを確認すると次の様になっています。
該当のソースコード
xaml
1<!-- Copyright (c) Microsoft Corporation and Contributors. --> 2<!-- Licensed under the MIT License. --> 3 4<Window 5 x:Class="teratail20230420.MainWindow" 6 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 7 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 8 xmlns:local="using:teratail20230420" 9 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 10 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 11 mc:Ignorable="d"> 12 13 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 14 <Button x:Name="myButton" Click="myButton_Click">Click Me</Button> 15 </StackPanel> 16</Window>
cs
1// Copyright (c) Microsoft Corporation and Contributors. 2// Licensed under the MIT License. 3 4using Microsoft.UI.Xaml; 5using Microsoft.UI.Xaml.Controls; 6using Microsoft.UI.Xaml.Controls.Primitives; 7using Microsoft.UI.Xaml.Data; 8using Microsoft.UI.Xaml.Input; 9using Microsoft.UI.Xaml.Media; 10using Microsoft.UI.Xaml.Navigation; 11using Python.Runtime; 12using System; 13using System.Collections.Generic; 14using System.IO; 15using System.Linq; 16using System.Runtime.InteropServices.WindowsRuntime; 17using Windows.Foundation; 18using Windows.Foundation.Collections; 19 20// To learn more about WinUI, the WinUI project structure, 21// and more about our project templates, see: http://aka.ms/winui-project-info. 22 23namespace teratail20230420 24{ 25 /// <summary> 26 /// An empty window that can be used on its own or navigated to within a Frame. 27 /// </summary> 28 public sealed partial class MainWindow : Window 29 { 30 public MainWindow() 31 { 32 this.InitializeComponent(); 33 } 34 35 private void myButton_Click(object sender, RoutedEventArgs e) 36 { 37 //myButton.Content = "Clicked"; 38 Runtime.PythonDLL = @".\pythondll\Python39.dll"; 39 PythonEngine.Initialize(); 40 41 using (Py.GIL()) 42 { 43 dynamic np = Py.Import("numpy"); 44 dynamic sin = np.sin; 45 myButton.Content = sin(0); 46 } 47 48 } 49 } 50} 51
試したこと
PythonEngineが残り続けていることで、正常に終了できていないと思い、終了イベントの時にPythonEngine.Shutdown();
を行えばよいのではと思い次の様に修正してみました。
C#
1 public sealed partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 this.InitializeComponent(); 6 7 Runtime.PythonDLL = @".\pythondll\Python39.dll"; 8 PythonEngine.Initialize(); 9 10 //終了イベント登録 11 Microsoft.UI.Windowing.AppWindow thisAppWin = GetCurrentAppWin(); 12 if(thisAppWin != null) 13 { 14 thisAppWin.Closing += (a, e) => 15 { 16 PythonEngine.Shutdown(); 17 }; 18 } 19 } 20 private Microsoft.UI.Windowing.AppWindow GetCurrentAppWin() 21 { 22 IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this); 23 WindowId winId = Win32Interop.GetWindowIdFromWindow(hwnd); 24 return Microsoft.UI.Windowing.AppWindow.GetFromWindowId(winId); 25 } 26 private void myButton_Click(object sender, RoutedEventArgs e) 27 { 28 //myButton.Content = "Clicked"; 29 using (Py.GIL()) 30 { 31 dynamic np = Py.Import("numpy"); 32 dynamic sin = np.sin; 33 myButton.Content = sin(0); 34 } 35 } 36 }
回答1件
あなたの回答
tips
プレビュー