質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

WinUI3

WinUI3は、Windowsデスクトップアプリ開発向けのネイティブUIフレームワークのバージョン3です。Windows10以降で採用されたFluentデザインに対応。直観的で使いやすい機能を備えています。

Q&A

解決済

1回答

983閲覧

WinUI3 で Python を呼び処理をさせるAppにおいて、Appを終了させてもタスクが残ってしまう。

MomenToufu

総合スコア10

.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

WinUI3

WinUI3は、Windowsデスクトップアプリ開発向けのネイティブUIフレームワークのバージョン3です。Windows10以降で採用されたFluentデザインに対応。直観的で使いやすい機能を備えています。

1グッド

0クリップ

投稿2023/04/20 07:13

実現したいこと

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 }

結果、Appを終了するために✕ボタンを押下したところ次のエラーが表示され、解決には至っていません。
イメージ説明

TN8001😄を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

次の様に、シャットダウンの前に
Python.Runtime.RuntimeData.FormatterType = typeof(NoopFormatter);
を入れることで、タスクが残ることも、システムエラーウインドウのUnknown Hard Errorも出なくなった。

C#

1// Copyright (c) Microsoft Corporation and Contributors. 2// Licensed under the MIT License. 3 4using Microsoft.UI; 5using Microsoft.UI.Xaml; 6using Microsoft.UI.Xaml.Controls; 7using Microsoft.UI.Xaml.Controls.Primitives; 8using Microsoft.UI.Xaml.Data; 9using Microsoft.UI.Xaml.Input; 10using Microsoft.UI.Xaml.Media; 11using Microsoft.UI.Xaml.Navigation; 12using Python.Runtime; 13using System; 14using System.Collections.Generic; 15using System.IO; 16using System.Linq; 17using System.Runtime.InteropServices.WindowsRuntime; 18using System.Runtime.Serialization; 19using Windows.Foundation; 20using Windows.Foundation.Collections; 21 22// To learn more about WinUI, the WinUI project structure, 23// and more about our project templates, see: http://aka.ms/winui-project-info. 24 25namespace teratail20230420 26{ 27 /// <summary> 28 /// An empty window that can be used on its own or navigated to within a Frame. 29 /// </summary> 30 public sealed partial class MainWindow : Window 31 { 32 public MainWindow() 33 { 34 this.InitializeComponent(); 35 36 Runtime.PythonDLL = @".\pythondll\Python39.dll"; 37 PythonEngine.Initialize(); 38 39 //終了イベント登録 40 Microsoft.UI.Windowing.AppWindow thisAppWin = GetCurrentAppWin(); 41 if (thisAppWin != null) 42 { 43 thisAppWin.Closing += (a, e) => 44 { 45 Python.Runtime.RuntimeData.FormatterType = typeof(NoopFormatter); 46 PythonEngine.Shutdown(); 47 }; 48 } 49 } 50 private Microsoft.UI.Windowing.AppWindow GetCurrentAppWin() 51 { 52 IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this); 53 WindowId winId = Win32Interop.GetWindowIdFromWindow(hwnd); 54 return Microsoft.UI.Windowing.AppWindow.GetFromWindowId(winId); 55 } 56 private void myButton_Click(object sender, RoutedEventArgs e) 57 { 58 //myButton.Content = "Clicked"; 59 using (Py.GIL()) 60 { 61 dynamic np = Py.Import("numpy"); 62 dynamic sin = np.sin; 63 myButton.Content = sin(0); 64 } 65 } 66 } 67 68 public class NoopFormatter : IFormatter 69 { 70 public object Deserialize(Stream s) => throw new NotImplementedException(); 71 public void Serialize(Stream s, object o) { } 72 public SerializationBinder Binder { get; set; } 73 public StreamingContext Context { get; set; } 74 public ISurrogateSelector SurrogateSelector { get; set; } 75 } 76} 77

投稿2023/04/21 00:58

MomenToufu

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問