1

スレッドを作成し、そのスレッドで画像を作成するプログラムを作成しました。

private async void GetCamera()
{
   ....
    tk = new Task(MyAwesomeTask);
    tk.Start();

}

private async void MyAwesomeTask()
{
        while (true)
        {
            await Task.Delay(TimeSpan.FromSeconds(0.5));
            SavePhoto1();
        }
}

private  void SavePhoto1()
{
        try
        {
            WriteableBitmap wb1 = new WriteableBitmap(320, 240);//throw exception
        }catch (Exception ee)
        {
            String s = ee.ToString();
        }

}

しかし、ライン

WriteableBitmap wb1 = new WriteableBitmap(320, 240); 

例外をスローします:

s = "System.Exception:別のスレッド用にマーシャリングされたインターフェイスを呼び出したアプリケーション。(HRESULTからの例外:0x8001010E(RPC_E_WRONG_THREAD))\ r \ n at Windows.UI.Xaml.Media.Imaging.WriteableBitmap..ctor( Int32 pixelWidth、Int32 pixelHeight)\ r \ n at TestVideo.MainPage.SetImageFromStream()in ... \ MainPage.xaml.cs:line 500 \ r \ n at TestVideo.MainPage.SavePhoto1()in .... \ MainPage .xaml.cs:line 145 "

私は何をする必要がありますか?

4

1 に答える 1

4

最初の問題は、を使用していることですasync void。これを行う必要があるのは、メソッドがイベントハンドラーの場合のみです。あなたの場合、async Task代わりに以下を使用する必要があります。

private async Task GetCamera()
{
   ....
    //tk = new Task(MyAwesomeTask);
    //tk.Start();
    await Task.Run(async () => await MyAwesomeTask());
    ...    
}

private async Task MyAwesomeTask()
{
    while (true)
    {
        await Task.Delay(TimeSpan.FromSeconds(0.5));
        // added await
        await SavePhoto1();
    }
}

Task上記のメソッドで実際にを返す必要はありません。コンパイラは自動的にそれを行います。

WriteableBitmap質問に答えるには、UIスレッドでのみオブジェクトを作成する必要があります。あなたはこれでそうすることができます:

private async Task SavePhoto1()
{
    try
    {
        WriteableBitmap wb1 = null;
        await ExecuteOnUIThread(() =>
        {
            wb1 = new WriteableBitmap(320, 240);//throw exception
        });

        // do something with wb1 here
        wb1.DoSomething();
    }catch (Exception ee)
    {
        String s = ee.ToString();
    }
}    

public static IAsyncAction ExecuteOnUIThread(Windows.UI.Core.DispatchedHandler action)
{
    return Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, action);
}

上記をコンパイルしてテストしませんでしたが、良いスタートを切ることができます。ご不明な点がございましたら、お気軽にお問い合わせください。

于 2013-03-26T17:23:58.747 に答える