2

最近、Windows Phone 7の作業を開始しました。デリゲートを作成し、非同期で呼び出そうとしました。コードは次のようなものでした:

public class1
{
     public delegate void fireAlwaysDelegate();
     fireAlwaysDelegate fad;
     public class1()
     {
       initializeComponents();
       fad=new fireAlwaysDelegate(fireAlways)
     }

     fireAlways()
     {
       //some code
     }

     PhoneApplicationPage_loaded()
     {
        //some code
        fda.beginInvoke(null,null);
     }
}

しかし、このコードを実行すると、.netCompactFrameworkは非同期でのデリゲートの呼び出しをサポートしていないという例外がスローされました。WP7フレームワークの私の理解によると、それはほとんどすべてに非同期呼び出しを使用するので、なぜこれが許可されないのか理解できません。

このことに対する回避策。

PhoneApplicationPage_loadedが完了し、UIが起動したら、コードを実行したかったので、PhoneApplicationPage_loadedから非同期デリゲートを呼び出すことを考えました。

また、デリゲートへの非同期呼び出しが許可されていない理由を理解したいと思います。

4

2 に答える 2

6

スレッドプールスレッドでデリゲートターゲットを呼び出す機能は、デリゲートにとってちょっと変わった機能です。これは「あると便利」のカテゴリに分類されますが、TPスレッドでコードを実行するために必須ではありません。実際の実装は氷山に似ており、別のスレッドで任意の引数を使用してスタックフレームを構築し、その存続期間を管理し、実行結果をキャプチャして呼び出し元のスレッドにマーシャリングできるようにするために必要なコードの巨大なチャンクがあります。

そのコードはCLRリモーティングサポートコードです。また、Compact Frameworkで始まり、SilverlightとWindowsPhoneに進化したCLRブランチにはありません。サイズが重要なプラットフォームでは、サイズを小さく保つためにカットされました。Silverlightの最大5メガバイトとデスクトップの最大50メガバイトを比較すると、かなりの偉業です。

別の方法は、代わりにThreadPool.QueueUserWorkItem()を使用することです。渡すことができる引数に制限があり、ラムダ式を使用してそれらをキャプチャすることで簡単に回避できます。少し心配する必要があるのは例外だけです。例外はワーカースレッドで発生し、そこでキャッチされない場合はアプリを終了します。

于 2012-10-23T10:13:15.183 に答える
1

代わりにBackgroundWorkerを使用できます。

public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    private BackgroundWorker bw = new BackgroundWorker();

    public MainPage()
    {
        InitializeComponent();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        FireAlways();
    }

  public void FireAlways()
  {
    //some code
  }

 private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
 {
     if (bw.IsBusy != true)
     {
         bw.RunWorkerAsync();
     }
 }

}
于 2012-10-23T09:07:49.473 に答える