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

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

新規登録して質問してみよう
ただいま回答率
85.45%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

1339閲覧

C# WPF MediaPlayer.MediaEndedイベントが発生しない場合がある

Hottopia

総合スコア16

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2023/03/11 00:43

前提

C# WPFで、ボタン等のクリック音を表現するため、以下のようにプログラムを作成しました。
ボタンクリック → MediaPlayerでmp3ファイルを再生 → MediaEndedイベントハンドラで処理を呼び出す。

発生している問題・エラーメッセージ

クリック音のようなごく短いファイルを再生した時、まれにMediaEndedイベントが発生しないケースがあります。
エラーメッセージ等は出ません。MediaElementを使用しても同様でした。

サンプルコードでは、ボタンクリック時にボタンのIsEnabledプロパティをfalseに設定しており(連打防止のため)、MediaEndedが発生しないとフリーズしたように見えます。
また、MediaEndedイベントハンドラ登録後に100msほどスリープさせると発生率が下がったような気がしますが、実際はわかりません。

該当のソースコード

MediaEndedTest1.xaml

XAML

1<Page x:Class="Test.MediaEndedTest.MediaEndedTest1" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:Test.MediaEndedTest" 7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800" 9 Title="MediaEndedTest1"> 10 11 <Grid> 12 <Button x:Name="Button" Content="To Page2" 13 Height="50" Width="200" 14 Click="Button_Click"/> 15 </Grid> 16</Page>

MediaEndedTest1.xaml.cs

C#

1using System; 2using System.Windows; 3using System.Windows.Controls; 4using System.Windows.Media; 5using System.Windows.Navigation; 6 7namespace Test.MediaEndedTest 8{ 9 /// <summary> 10 /// MediaEndedTest1.xaml の相互作用ロジック 11 /// </summary> 12 public partial class MediaEndedTest1 : Page 13 { 14 public MediaEndedTest1() 15 { 16 InitializeComponent(); 17 } 18 19 private void Button_Click(object sender, RoutedEventArgs e) 20 { 21 var pushedButton = (Button)sender; 22 pushedButton.IsEnabled = false; 23 var pushSound = new MediaPlayer(); 24 pushSound.MediaEnded += (sender, e) => 25 { 26 var mediaEndedTest2 = new MediaEndedTest2(); 27 NavigationService.Navigate(mediaEndedTest2); 28 }; 29 pushSound.Open(new Uri(//クリック音のmp3ファイル//, UriKind.Relative)); 30 pushSound.Play(); 31 } 32 } 33}

MediaEndedTest2.xaml

XAML

1<Page x:Class="Test.MediaEndedTest.MediaEndedTest2" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:Test.MediaEndedTest" 7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800" 9 Title="MediaEndedTest2"> 10 11 <Grid> 12 <Button x:Name="Button" Content="To Page1" 13 Height="50" Width="200" 14 Click="Button_Click"/> 15 </Grid> 16</Page>

mediaEndedTest2.xaml.cs

C#

1using System; 2using System.Collections.Generic; 3using System.Text; 4using System.Threading; 5using System.Windows; 6using System.Windows.Controls; 7using System.Windows.Data; 8using System.Windows.Documents; 9using System.Windows.Input; 10using System.Windows.Media; 11using System.Windows.Media.Imaging; 12using System.Windows.Navigation; 13using System.Windows.Shapes; 14 15namespace Test.MediaEndedTest 16{ 17 /// <summary> 18 /// MediaEndedTest2.xaml の相互作用ロジック 19 /// </summary> 20 public partial class MediaEndedTest2 : Page 21 { 22 public MediaEndedTest2() 23 { 24 InitializeComponent(); 25 } 26 27 private void Button_Click(object sender, RoutedEventArgs e) 28 { 29 var pushedButton = (Button)sender; 30 pushedButton.IsEnabled = false; 31 var pushSound = new MediaPlayer(); 32 pushSound.MediaEnded += (sender, e) => 33 { 34 var mediaEndedTest1 = new MediaEndedTest1(); 35 NavigationService.Navigate(mediaEndedTest1); 36 }; 37 pushSound.Open(new Uri( //クリック音のmp3ファイル//, UriKind.Relative)); 38 pushSound.Play(); 39 } 40 } 41} 42

補足情報(FW/ツールのバージョンなど)

Visual Studio 2022
C#10.0
WPF

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

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

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

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

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

TN8001

2023/03/11 03:22

> var pushSound = new MediaPlayer(); pushSound がローカル変数だとGCされませんかね? フィールドに保持するとどうでしょう。 > MediaEndedイベントハンドラ登録後に100msほどスリープさせると発生率が下がったような気がします 音を出すことが決定しているなら MediaEnded+= 自体コンストラクタに移動できそうですが。
Hottopia

2023/03/11 05:42

フィールドでpushSoundを保持し、MediaEndedイベントハンドラをコンストラクタで宣言するようにしてみました。 オートクリックツールで20分くらいテストして、とりあえずは発生しなくなったようです。 このやり方だと、ボタンが複数あり、それぞれ違う処理を行いたい場合、その分だけMediaPlalyerのフィールドもイベントハンドラも増えることになりませんか? 今回はそれほど多くないので、この方法を使わせていただこうかと思います。ありがとうございます。
TN8001

2023/03/11 07:05

> このやり方だと、ボタンが複数あり、それぞれ違う処理を行いたい場合、その分だけMediaPlalyerのフィールドもイベントハンドラも増えることになりませんか? ボタンが複数あり同時に鳴ることが**ある**なら、MediaPlalyerも複数必要になりますよね。 ボタンが複数あり同時に鳴ることが**ない**なら、MediaPlalyerはひとつで十分なはずですよね。 でもあれこれ考えるのもめんどくさいっすね^^; もし**GC説が正しいのであれば**↓こんなのでもいい気はします。 var button = (Button)sender; var mediaPlayer = new MediaPlayer(); button.Tag = mediaPlayer; mediaPlayer.MediaEnded += (sender, e) => { }; あるいはお得意のStoryboardとかでもできないですかね?(かえって話がややこしくなるかw > 今回はそれほど多くないので、この方法を使わせていただこうかと思います。ありがとうございます。 ちょっと様子を見ていただいて問題がなければ、お手数ですが自己解決で閉じてください。
guest

回答1

0

自己解決

TN8001 さんがコメントして下さった、MediaPlayerをフィールドで保持する方法で数日程度様子を見ましたが、今のところ発生していないようなので解決とし、質問をクローズさせていただきます。

コメントして下さった TN8001 さん 、 ありがとうございました。

投稿2023/03/14 07:19

Hottopia

総合スコア16

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.45%

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

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

質問する

関連した質問