いくつかのデータを表示し、バックグラウンド エージェントを起動してライブ タイルを動的に更新するアプリがあります。ライブ タイルのコンテンツは、メイン スレッドから入力された変数を使用してバックグラウンド エージェントで作成されるため、メイン間で共有する静的変数とプロパティを含むクラスを作成することにしました (これは間違った決定だったのかもしれませんが、これが唯一合理的だと思いました)。スレッドおよびバックグラウンド エージェント。ここでの問題は、メイン スレッドに変数値を書き込むことですが、バックグラウンド エージェントが実行されると、この値が 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 プロジェクト内にあるためでしょうか (それを実行する必要があります)。
異なるスレッド間で共有できる、初めて作成された単一のクラスを作成する方法はありますか (この状況ではプロセスですか?)。