0

ImageOpened()セカンダリ ライブ タイルをカスタム イメージで更新するために、すべてのイベント (この場合は 3 つ) が発生する前にバックグラウンド エージェントの実行を待機させるにはどうすればよいですか?

編集1:

OnInvoke()メソッドではScheduledAgent、共有ライブラリに実装された独自のタイル データ作成関数を呼び出しています。共有ライブラリはImageOpened()、すべてのライブ タイル テンプレート (小、中、ワイド) のカスタム イメージを作成しようとしているときに、3 つのイベントをサブスクライブします。

これらは非同期イベントであるため、すべてのイベントが正常に完了したかどうかを確認する方法がないため、呼び出しNotifyComplete()てバックグラウンド エージェントにジョブが完了したことを通知できます。そのため、タイルが更新されることもありますが、ほとんどの場合は更新されません。また、アプリを起動するたびに同じ関数を使用してライブ タイルを更新しているので、実装に問題はありません。GC.Collect()また、ビットマップを破棄して強制的に呼び出すことで、ScheduledAgent のすべてのメモリ制限に対処しようとしました。

この問題を解決するために、可能な方法で助けてください。

4

1 に答える 1

1

カスタム イベントを作成できる新しいクラスを追加します。

public class SaveImageCompleteEventArgs : EventArgs
{
    public bool Success { get; set; }
    public Exception Exception { get; set; }
    public string ImageFileName { get; set; }

    public SaveImageCompleteEventArgs(bool success, string fileName)
    {
        Success = success;
        ImageFileName = fileName;
    }
}

カスタム ライブ タイルの更新元のファイルで、イベントと必要な変数を初期化します。

public static int countTile = 3;
public event EventHandler<SaveImageCompleteEventArgs> SaveMediumImageComplete;
public event EventHandler<SaveImageCompleteEventArgs> SaveWideImageComplete;
public event EventHandler<SaveImageCompleteEventArgs> SaveSmallImageComplete;
public event EventHandler<SaveImageCompleteEventArgs> SaveAllImagesComplete;

ImageOpened()すべてのタイルのイベント ハンドラーで完了イベントを発生させ、イベントSaveAllImagesCompleteを発生させる必要があるかどうかを確認します。

public void OnBackgroundBmpOpenedMedium(object sender, RoutedEventArgs e)
{
    if (SaveMediumImageComplete != null)
    {
        countTile -= 1;
        CheckIfAllImagesOpened();
        SaveMediumImageComplete(this, new SaveImageCompleteEventArgs(true, mediumTileImageUriIronMan));
    }
}

private void CheckIfAllImagesOpened()
{
    if (countTile == 0)
    {
        if (SaveAllImagesComplete != null)
        {
            var args1 = new SaveImageCompleteEventArgs(true, "");
            SaveAllImagesComplete(this, args1);
        }
    }
}

ScheduledAgent ファイル内 -

public static ManualResetEvent evt;
public bool IsPaused { get { return !evt.WaitOne(0); } }

OnInvoke() 関数で -

evt = new ManualResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
    //Initialize secondary tile here

    if (secondaryTile != null)
    {
        /* 
        obj is a object of a helper file that contains all the  
        functions responsible for updating the custom live tile

        Call the function that is responsible for initializing all the  
        tile image bitmpas and that subscribes to the ImageOpened events 
        */

        obj.SaveMediumImageComplete += async (s, args) =>
        {
            if (!IsPaused)
                evt.Set();
        };
        obj.SaveWideImageComplete += async (s, args) =>
        {
            if (!IsPaused)
                evt.Set();
        };
        obj.SaveSmallImageComplete += async (s, args) =>
        {
            if (!IsPaused)
                evt.Set();
        };
        obj.SaveAllImagesComplete += async (s, args) =>
        {
            try
            {
                if (args.Success)
                    obj.UpdateTileIcon();
            }
            catch (Exception) { }
            finally
            {
                if (!IsPaused)
                    evt.Set();
            }
        };
    }
});
evt.WaitOne();
NotifyComplete();
于 2015-03-22T10:16:47.157 に答える