locked
VB.net で WriteableBitmap が使用できない RRS feed

  • 質問

  • WindowsPhone による C# の画像保存処理サンプルを元に、同様の処理を VB.net で記述してみたのですが、先頭行でエラーが発生してしまいます。

    エラーメッセージ・エラー詳細・C#のサンプルコード・それを元に書いた VB.net のコードを提示します。

    原因および解決策についてご教授いただきたくよろしくお願いいたします。

    エラーメッセージ

    System.UnauthorizedAccessException はハンドルされませんでした。

    エラー詳細

      Message=Invalid cross-thread access.
      StackTrace:
           at MS.Internal.XcpImports.CheckThread()
           at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
           at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex)
           at System.Windows.Media.ImageSource..ctor(UInt32 nKnownTypeIndex)
           at System.Windows.Media.Imaging.BitmapSource..ctor(UInt32 nKnownTypeIndex)
           at System.Windows.Media.Imaging.WriteableBitmap..ctor(UIElement element, Transform transform)
           at DessinFlame.MainPage.cam_CaptureThumbnailAvailable(Object sender, ContentReadyEventArgs e)
           at Microsoft.Devices.PhotoCamera.<>c__DisplayClass5.<HandleImageReady>b__2(Object ignored)
           at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadPool.WorkItem.doWork(Object o)
           at System.Threading.Timer.ring()
      InnerException:

    C#

            //Grid から Jpeg 保存用ストリームを作成
            WriteableBitmap wp = new WriteableBitmap(grdFlame, null);
            MemoryStream stream = new MemoryStream();
            wp.SaveJpeg(stream, wp.PixelWidth, wp.PixelHeight, 0, 100);

            //PictureHub に保存する
            using (MediaLibrary lib = new MediaLibrary())
            {
                lib.SavePicture("DessinFlame_" + DateTime.Now.ToString("yyyyMMdd_hhmmss") + ".jpg", stream.ToArray());
                MessageBox.Show("保存しました");
            }

    VB.net

            Dim objWriteableBitmap As WriteableBitmap =  New WriteableBitmap(grdFlame, Nothing)
            Dim objMemoryStream As MemoryStream = New MemoryStream
            objWriteableBitmap.SaveJpeg(objMemoryStream, objWriteableBitmap.PixelWidth, objWriteableBitmap.PixelHeight, 0, 100)
            Using objMediaLibrary As MediaLibrary = New MediaLibrary
                objMediaLibrary.SavePicture(strFileName, objMemoryStream.ToArray())
            End Using

    • 移動 Mike Wang (MSCS) 2012年10月2日 11:01 (移動元:Windows Phone 7 How-to)
    2012年8月25日 11:21

回答

  •   Message=Invalid cross-thread access.

    このあたりは経験によるかもしれませんが、「Invalid cross-thread access」という文言から、正しいスレッドでコードを実行していないことが問題と予想できます。
    Windows Phone は非同期処理の完了通知が別スレッドで通知されることが多くなっています。
    その反面、別スレッドでは扱えないクラスもありますので、その場合は Dispatcher.BeginInvoke などを使う必要があります。

    実際、CaptureThumbnailAvailable で検索してサンプルを探すと、以下のページが見つかりますが、BeginInvoke が登場していますね。
    http://msdn.microsoft.com/ja-jp/library/hh202956(v=vs.92).aspx

    // C# だから、VB.NET だからという前に、本当にそうかは疑いましょう。
    // 切り分けできない場合は、原因を断定的に書くのではなく、事実と推測を分けて書きましょう。

    • 回答としてマーク Tech-Bee 2012年8月25日 15:05
    2012年8月25日 12:55
    モデレータ

すべての返信

  •   Message=Invalid cross-thread access.

    このあたりは経験によるかもしれませんが、「Invalid cross-thread access」という文言から、正しいスレッドでコードを実行していないことが問題と予想できます。
    Windows Phone は非同期処理の完了通知が別スレッドで通知されることが多くなっています。
    その反面、別スレッドでは扱えないクラスもありますので、その場合は Dispatcher.BeginInvoke などを使う必要があります。

    実際、CaptureThumbnailAvailable で検索してサンプルを探すと、以下のページが見つかりますが、BeginInvoke が登場していますね。
    http://msdn.microsoft.com/ja-jp/library/hh202956(v=vs.92).aspx

    // C# だから、VB.NET だからという前に、本当にそうかは疑いましょう。
    // 切り分けできない場合は、原因を断定的に書くのではなく、事実と推測を分けて書きましょう。

    • 回答としてマーク Tech-Bee 2012年8月25日 15:05
    2012年8月25日 12:55
    モデレータ
  • 確かにおっしゃるとおりでした。

    非同期処理についてまだぜんぜん理解ができていなくて恥ずかしいです。

    ご指摘いただいた内容を元になんとか自分なりに望んでいた機能を実装することが出来ました。

    「デッサンフレーム」といいます。

    画学生がデッサンをする際に構図を決めるために用いることを想定しています。

    問題がなければ9月上旬には AppHUB に掲載していただけると思います。

    どうもありがとうございました。

    2012年8月25日 15:11