3

我有一个应用程序,它显示一些数据并启动一个后台代理来动态更新动态磁贴。由于使用从主线程填充的一些 var 在后台代理中创建动态图块内容,我决定(也许这是一个错误的决定,但这是我认为唯一合理的决定)编写一个具有静态变量和属性的类以在主线程之间共享线程和后台代理。现在的问题是我在主线程中写了一个变量值,但是当后台代理执行时发现这个值是空的。为什么?
我提供了一个小例子,跳跃它足以让你理解。

静态部分

public class Vars
{
    public static IEnumerable<Contact> Contacts;
    public static void Test()
    {
        int num = Contacts == null ? -2 : Contacts.Count();
        // num is -2 here because Contacts is null !!
    }
}

背景代理

public class TileAgent : ScheduledTaskAgent
{
    protected override void OnInvoke(ScheduledTask task)
    {
        // It's necessary to use BeginInvoke to avoid Cross-thread errors
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            Vars.Test();
        });

        NotifyComplete();
    }
}

主页

public partial class MainPage : PhoneApplicationPage
{
    private void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
    {
        busyIndicator.IsRunning = false;
        try
        {
            Vars.Contacts = e.Results
                .Where(.........);
            ContactResultsData.DataContext = Vars.Contacts;
            // Vars.Contacts.Count() = 67 here !!!

            if (Vars.GetTile() != null)
                StartAgent();
        }
        catch (System.Exception)
        {
            // That's okay, no results
        }
    }
    private void ContactResultsData_Tap(object sender, GestureEventArgs e)
    {
        int num = Vars.Contacts == null ? -2 : Contacts.Count();
        // num = 67 here !!
   }
}

我的代码有什么问题?有没有更好的方法来完成我的任务?
考虑到我从不到一个月的时间开始就在 Windows Phone 上工作,所以我确信我仍然在做非常糟糕的事情......

更新
在放置正确的锁以避免来自不同线程的并发读/写之后,我决定将显式静态构造函数放入静态类

public class Vars
{
    static Vars()
    {
        Debug.WriteLine("init");
    }
}

每次调用后台代理时都会调用它!
这解释了我看到我的变量为空的原因,但我不明白:为什么每次都重新创建一个静态类?
可能是因为后台代理位于 dll 项目中(必须运行它)?
有没有办法制作一个只在第一次创建的类,可以在不同的线程之间共享(在这种情况下它们是进程吗?)?

4

3 回答 3

4

找了好久,终于找到一篇文章说:

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

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

我觉得这很疯狂,但这就是故事。

于 2012-07-09T07:58:05.740 回答
1

您需要同步对共享集合的访问。现在一个线程可以读取它(通过Count()在另一个写入时调用,这是非常糟糕的。

于 2012-07-05T15:28:14.977 回答
0

我认为将 volatile 修饰符添加到您的变量可以解决您的问题。

于 2012-07-05T15:10:57.603 回答