在主应用和定期任务之间共享数据

我发布了另一个我无法解决的具体问题。

简而言之:即使我创建了一个静态类(具有静态变量和/或属性),主应用程序和后台代理也不使用相同的静态类,但都创建了它的新实例; 所以在这些项目之间共享数据是不可能的!

测试它:

  • 创建一个新的Windows Phone应用程序(称为AppTest
  • 添加ScheduledTask项目(称为Agent
  • AppTest中添加对项目代理的引用
  • 创建一个新的Windows Phone Library项目(称为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 Apps = null; public static int Order; static Vars() { Apps = new List(); Order = -1; } } 

当您调试主应用程序时,您可以看到静态类的静态构造函数被调用(这是正确的),但是当调用代理时, Vars不会被“使用”,但是构造函数会被另一次调用,因此创建一个不同的实例。
为什么? 如何在主应用和后台代理之间共享数据?
我已经尝试将Vars类放在代理类和命名空间中,但行为是一样的。

静态变量的值是每个加载的App Domain “实例化”,它是正在运行的进程的“子集”。 因此,静态变量每个AppDomain具有不同的值,因此每个运行的进程也是如此。

如果必须在进程之间共享数据,则需要将其存储在某个位置(例如数据库),或者需要在进程之间建立一些通信(例如MSMQ或WCF)。

希望这可以帮助。

最简单的方法是使用独立存储。 例如,从主应用程序:

 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... 

您需要使用进程级同步和Mutex来防止数据损坏,因为代理和应用程序是两个独立的进程,可能同时使用隔离存储执行某些操作。

经过长时间的搜索,我终于发现一篇文章说:

由于我们的EvenTiles应用程序及其PeriodicTask在不同的进程中运行,因此它们彼此完全分离,这意味着它们获得了自己想要访问的变量的副本,即使这些变量是在单独的项目中定义的。

因此,使用“简单”静态变量/属性在主应用程序和周期性任务之间共享数据是不可能的; 我们必须读/写数据库或隔离存储或任何我们想要的东西。

我发现这很疯狂,但这就是故事。

MS建议如下:

前景应用与后台代理之间的通信

在前台应用程序和后台代理之间传递信息可能具有挑战性,因为无法预测代理和应用程序是否同时运行。 以下是推荐的模式。

1.对于定期和资源密集型代理:使用LINQ 2 SQL或隔离存储中使用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