8

この特定の質問を、解決できなかっ た次の質問の後に投稿します。

簡単に言うと、静的クラス(静的変数やプロパティを使用)を作成した場合でも、メインアプリとバックグラウンドエージェントは同じ静的クラスを使用しませんが、両方ともその新しいインスタンスを作成します。したがって、これらのプロジェクト間でデータを共有することは不可能です!!

それをテストするには:

  • 新しいWindowsPhoneアプリケーション(AppTestと呼ばれる)を作成します
  • ScheduledTaskプロジェクト(エージェントと呼ばれる)を追加します
  • AppTestに、プロジェクトエージェントへの参照を配置します
  • 新しいWindowsPhoneライブラリプロジェクト(Sharedと呼ばれる)を作成します
  • AppTestAgentの両方で、プロジェクトSharedへの参照を配置します

次に、この基本的なテストコードを使用します。

AppTest

private readonly string taskName = "mytest";
PeriodicTask periodicTask = null;

public MainPage()
{
    InitializeComponent();

    Vars.Apps.Add("pluto");
    Vars.Order = 5;

    StartAgent();
}

private void RemoveTask()
{
    try
    {
        ScheduledActionService.Remove(taskName);
    }
    catch (Exception)
    {
    }
}
private void StartAgent()
{
    periodicTask = ScheduledActionService.Find(taskName) as PeriodicTask;
    if (periodicTask != null)
        RemoveTask();
    periodicTask = new PeriodicTask(taskName)
    {
        Description = "test",
        ExpirationTime = DateTime.Now.AddDays(14)
    };

    try
    {
        ScheduledActionService.Add(periodicTask);
        ScheduledActionService.LaunchForTest(taskName, 
                TimeSpan.FromSeconds(10));
    }
    catch (InvalidOperationException exception)
    {
    }
    catch (SchedulerServiceException)
    {
    }
}

エージェント

protected override void OnInvoke(ScheduledTask task)
{
    if (Vars.Apps.Count > 0) 
        Vars.Order = 1;

    NotifyComplete();
}

共有

public static class Vars
{
    public static List<string> Apps = null;
    public static int Order;

    static Vars()
    {
        Apps = new List<string>();
        Order = -1;
    }
}

メインアプリをデバッグすると、静的クラスの静的コンストラクターが呼び出されることがわかります(これは正しいです)が、エージェントが呼び出されるVarsと「使用」されず、コンストラクターが別のときに呼び出されるため、別のインスタンスを作成します。
なんで?メインアプリとバックグラウンドエージェントの間でデータを共有するにはどうすればよいですか?
私はすでにVarsクラスをエージェントクラスと名前空間に入れようとしましたが、動作は同じです。

4

4 に答える 4

8

最も簡単なのは、分離ストレージを使用することです。たとえば、メインアプリから:

using (Mutex mutex = new Mutex(true, "MyData"))
{
    mutex.WaitOne();
    try
    {
        IsolatedStorageSettings.ApplicationSettings["order"] = 5;
    }
    finally
    {
        mutex.ReleaseMutex();
    }
}
//...

およびエージェント内:

using (Mutex mutex = new Mutex(true, "MyData"))
{
    mutex.WaitOne();
    try
    {
        order = (int)IsolatedStorageSettings.ApplicationSettings["order"];
    }
    finally
    {
        mutex.ReleaseMutex();
    }
}

// do something with "order" here...

エージェントとアプリは2つの別個のプロセスであり、分離されたストレージで同時に何かを実行する可能性があるため、データの破損を防ぐためにプロセスレベルの同期とMutexを使用する必要があります。

于 2012-07-10T18:35:12.410 に答える
5

静的変数の値は、ロードされたApp Domainごとに「インスタンス化」されます。これは、実行中のプロセスの「サブセット」です。したがって、静的変数はAppDomainごとに、したがって実行中のプロセスごとにも異なる値を持ちます。

プロセス間でデータを共有する必要がある場合は、データをどこかに保存するか(データベースなど)、プロセス間で通信を設定する必要があります(MSMQやWCFなど)。

お役に立てれば。

于 2012-07-09T06:40:00.827 に答える
3

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

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

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

これはおかしいと思いますが、これが物語です。

于 2012-07-09T07:46:02.630 に答える
2

MSは次のことを推奨しています。

フォアグラウンドアプリケーションとバックグラウンドエージェント間の通信

フォアグラウンドアプリケーションとバックグラウンドエージェントの間で情報を渡すことは、エージェントとアプリケーションが同時に実行されるかどうかを予測できないため、困難な場合があります。これに推奨されるパターンは次のとおりです。

1.定期的でリソースを大量に消費するエージェントの場合:LINQ2SQLまたはMutexで保護されている分離ストレージ内のファイルを使用します。フォアグラウンドアプリケーションが書き込み、エージェントが読み取りのみを行う一方向通信の場合、Mutexで分離されたストレージファイルを使用することをお勧めします。データが破損する可能性があるため、プロセス間の通信にIsolatedStorageSettingsを使用しないことをお勧めします。

2.オーディオエージェントの場合:AudioTrackクラスのTagプロパティにカスタムデータを保存します。オーディオエージェントからフォアグラウンドアプリケーションへの通知については、PlayStateChangedイベントハンドラーのTagプロパティをお読みください。フォアグラウンドアプリケーションからオーディオエージェントにデータを渡すには、OnPlayStateChanged(BackgroundAudioPlayer、AudioTrack、PlayState)メソッドの実装で現在のトラックのTagプロパティを読み取ります。

ここを参照してください:http://msdn.microsoft.com/en-us/library/hh202944 (v = vs.92).aspx

于 2012-08-26T10:56:54.270 に答える