UWP で RPC_E_WRONG_THREAD が発生した場合の対処方法

この記事は公開されてから時間が経っています

最近、故有って Windows 10 のアプリケーションを作ってるんですが、この手のツールを使うのがすごく久しぶりな上、Visual Studio 2015 で C# と来たもんだ ^^/
昔は Delphi/BCB だったから VS 2015 をはじめてから2週間はまともにコードがかけなかったよ..
で、 とフォームアプリの違いと Windows-universal-samples-master を眺めるのに数週間を費やしてしまった…

で、UWP アプリをなんとなく動くようになるまで2ヶ月かかってしまった
その間苦労したことも、せっかくなので忘れないように書いておこう!と言う試み


或るイベントの処理を開始したときに、音を鳴らしたいと思って試行錯誤していた
取り合えず、とあるクラス中で音を一定間隔で鳴らしていたとき、次の感じで再生出来ていた
 

    private MediaElement me;

    private async void Run(){

            me = new MediaElement();             //    音源の準備

            var uri = new Uri("ms-appx:///Assets/sound.wav");
            var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
            var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);

            me.AutoPlay = false;
            me.SetSource(stream, file.ContentType);
            me.Volume = 0.3;
        …
        while(true){

        …
            me.Play();
        …
        }
    }

 この処理は一定間隔で、バインディングされた UI に文字を書き続けると言うクラスの中の実行部分で書いていた
※ 音を一定間隔で鳴らすのがこのときの主眼だったのでそれ以外は、UWP & C# 初心者なのでいい加減

で、この一連の再生手順を、任意のタイミングで発生するイベント処理の中に組み込もうと思って、そのままコピペしたら

アプリケーションは、別のスレッドにマーシャリングされたインターフェイスを呼び出しました。
(Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

と言う例外が発生して停止してしまいました

で、解決する方法はこんな感じ

        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
        {
            me.Play();
        });

この、Play() だけがイベント発生時によばれて、MediaElement の初期化はイベントの登録前に処理しておきます
何度もイッパツで再生出来るので何かと便利


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です