Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

c# - Share data between main app and periodic task

I post this specific question after the other one I wasn't able to solve.

Briefly: even if I create a static class (with static vars and/or properties), main app and background agent don't use the same static class, but both create a new instance of it; so it's impossible to share data between these projects!!

To test it:

  • Create a new Windows Phone application (called AppTest)
  • Add a ScheduledTask project (called Agent)
  • In AppTest put a reference to project Agent
  • Create a new Windows Phone Library project (called Shared)
  • Both in AppTest and Agent put a reference to project Shared

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 main app you can see that static constructor for static class is invoked (this is correct), but when agent is invoked Vars is not "used" but constructor is invoked another time, so creating a different instance.
Why? How can I share data between main app and background agent?
I've already tried to put Vars class in agent class and namespace, but the behaviour is the same.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Easiest thing is to use Isolated storage. For example, from the main app:

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 Process-level synchronization and Mutex to guard against data corruption because the agent and the app are two separate processes and could be doing something with isolated storage at the same time.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...