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

时间:2012-07-09 06:33:44

标签: c# windows-phone-7

我在other one无法解决之后发布了这个具体问题。

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

测试它:

  • 创建新的Windows Phone应用程序(名为 AppTest
  • 添加ScheduledTask项目(称为代理
  • AppTest 中添加项目代理
  • 的引用
  • 创建一个新的Windows Phone Library项目(名为共享
  • AppTest 代理商都会对项目共享
  • 进行引用

然后使用此基本测试代码。

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 个答案:

答案 0 :(得分: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...

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

答案 1 :(得分:5)

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

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

希望这有帮助。

答案 2 :(得分:3)

经过长时间的搜索,我终于找到了article说明:

  

因为我们的EvenTiles应用程序及其PeriodicTask正在运行   分开的过程,它们完全相互分离,   这意味着他们得到了他们想要的变量副本   访问,即使这些变量是在一个单独的项目中定义的。

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

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

答案 3 :(得分:2)

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