3

いくつかのデータを表示し、バックグラウンド エージェントを起動してライブ タイルを動的に更新するアプリがあります。ライブ タイルのコンテンツは、メイン スレッドから入力された変数を使用してバックグラウンド エージェントで作成されるため、メイン間で共有する静的変数とプロパティを含むクラスを作成することにしました (これは間違った決定だったのかもしれませんが、これが唯一合理的だと思いました)。スレッドおよびバックグラウンド エージェント。ここでの問題は、メイン スレッドに変数値を書き込むことですが、バックグラウンド エージェントが実行されると、この値が null であることがわかります。なんで?
小さな例を示しますが、理解するのに十分です。

静的部分

public class Vars
{
    public static IEnumerable<Contact> Contacts;
    public static void Test()
    {
        int num = Contacts == null ? -2 : Contacts.Count();
        // num is -2 here because Contacts is null !!
    }
}

バックグラウンド エージェント

public class TileAgent : ScheduledTaskAgent
{
    protected override void OnInvoke(ScheduledTask task)
    {
        // It's necessary to use BeginInvoke to avoid Cross-thread errors
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            Vars.Test();
        });

        NotifyComplete();
    }
}

メインページ

public partial class MainPage : PhoneApplicationPage
{
    private void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
    {
        busyIndicator.IsRunning = false;
        try
        {
            Vars.Contacts = e.Results
                .Where(.........);
            ContactResultsData.DataContext = Vars.Contacts;
            // Vars.Contacts.Count() = 67 here !!!

            if (Vars.GetTile() != null)
                StartAgent();
        }
        catch (System.Exception)
        {
            // That's okay, no results
        }
    }
    private void ContactResultsData_Tap(object sender, GestureEventArgs e)
    {
        int num = Vars.Contacts == null ? -2 : Contacts.Count();
        // num = 67 here !!
   }
}

コードの何が問題になっていますか? 私の仕事を達成するためのより良い方法はありますか?
私が Windows Phone に取り組んでからまだ 1 か月も経っていないことを考えてみてください。

更新:
異なるスレッドからの同時読み取り/書き込みを回避するために正しいロックを配置した後、明示的な静的コンストラクターを静的クラスに配置することにしました

public class Vars
{
    static Vars()
    {
        Debug.WriteLine("init");
    }
}

これは、バックグラウンド エージェントが呼び出されるたびに呼び出されます!!
これは、変数が null として表示される理由を説明していますが、理解できません。静的クラスが毎回再作成されるのはなぜですか?
バックグラウンド エージェントが dll プロジェクト内にあるためでしょうか (それを実行する必要があります)。
異なるスレッド間で共有できる、初めて作成された単一のクラスを作成する方法はありますか (この状況ではプロセスですか?)。

4

3 に答える 3

4

長い間検索した後、最終的に次のような記事を見つけました。

EventTiles アプリケーションとその PeriodicTask は別々のプロセスで実行されているため、互いに完全に分離されています。つまり、これらの変数が別のプロジェクトで定義されていても、両方がアクセスしたい変数の独自のコピーを取得します。

そのため、「単純な」静的変数/プロパティを使用して、メイン アプリと定期的なタスクの間でデータを共有することは不可能です。データベースや分離ストレージなど、好きなものを読み書きする必要があります。

これはクレイジーだと思いますが、これが話です。

于 2012-07-09T07:58:05.740 に答える
1

共有コレクションへのアクセスを同期する必要があります。現在、1 つのスレッドがそれを読み取ることができます (Count()他のスレッドが書き込み中に呼び出すことによって)。これは非常に悪いことです。

于 2012-07-05T15:28:14.977 に答える
0

変数に揮発性修飾子を追加すると、問題を解決できると思います。

于 2012-07-05T15:10:57.603 に答える