Sharing data between the main application and the periodic task

I am posting this specific question after another which I could not solve.

In short: even if I create a static class (with static options and / or properties), the main application and the background agent do not use the same static class, but both create a new instance; therefore, it is not possible to exchange data between these projects.

To check this:

  • Create a new Windows Phone app (called AppTest )
  • Add a ScheduledTask project (called Agent )
  • In AppTest, put a link to the Agent project
  • Create a new Windows Phone Library project (called Shared )
  • Both in AppTest and Agent put a link to the General project.

Then use this basic test code.

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) { } } 

Agent

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

Shared

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

When you debug the main application, you can see that the static constructor for the static class is called (this is correct), but when the agent is called, Vars not used, but the constructor is called at another time, therefore creating another instance.
What for? How can I exchange data between the main application and the background agent?
I already tried putting the Vars class in the agent class and namespace, but the behavior is the same.

+8
c # windows-phone-7
source share
4 answers

The values ​​of the static variables are "instanced" for the loaded application domain , which is a "subset" of your current process. Thus, static variables have different meanings for the AppDomain and therefore also for each process.

If you need to exchange data between processes, you need to either store them somewhere (for example, a database), or you need to configure some communication between processes (for example, MSMQ or WCF).

Hope this helps.

+5
source share

The easiest way is to use isolated storage. For example, from the main application:

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

and in the agent:

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

You need to use synchronization at the process level and Mutex to protect against data corruption, since the agent and the application are two separate processes and can do something with isolated storage at the same time.

+8
source share

After a long search, I finally found an article stating:

Since our EvenTiles application and its PeriodicTask work in separate processes, they are completely separate from each other so that they get their own copies of the variables that they both want access to, although these variables are defined in a separate project.

Thus, it is not possible to exchange data between the main application and the periodic task using "simple" static variables / properties; we must read / write a database or isolated storage or whatever.

I find it crazy, but it's a story.

+3
source share

MS recommends the following:

Relationship between Foreground Application and Background Agent

Transferring information between the front-end application and background agents can be a difficult task because it is impossible to predict whether the agent and the application will work at the same time. The following templates are recommended for this.

1. For periodic and resource-intensive agents: use LINQ 2 SQL or a file in isolated storage that is protected with Mutex. For unidirectional communication, in which the foreground application is written and the agent is only reading, we recommend using an isolated storage file with Mutex. We do not recommend using IsolStorageSettings for communication between processes, because data can become corrupted.

2.For Audio Agents: saving user data in the Tag property of the AudioTrack class. For notifications from the audio agent to the front-end application, read the Tag property in the PlayStateChanged event handler. To transfer data from the foreground application to the sound agent, read the Tag property of the current track in the implementation of the OnPlayStateChanged method (BackgroundAudioPlayer, AudioTrack, PlayState).

See here: http://msdn.microsoft.com/en-us/library/hh202944(v=vs.92).aspx

+2
source share

All Articles