我有一个应用程序,可以显示一些数据并启动后台代理来动态更新动态图块。由于动态图块内容是在后台代理中使用从主线程填充的一些变量创建的,因此我决定(也许这是一个错误的决定,但这是我认为唯一合理的决定)编写一个具有静态变量和属性的类以在主线程之间共享线程和后台代理。
现在的问题是我在主线程中编写了一个变量值,但是当后台代理执行时发现该值为空。为什么?
我举一个小例子,希望你能理解。
静态部分
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 上工作还不到一个月,所以我确信我仍然在做非常糟糕的事情......
UPDATE:
在放置正确的锁以避免不同线程的并发读/写之后,我决定将显式静态构造函数放入静态类
public class Vars
{
static Vars()
{
Debug.WriteLine("init");
}
}
每次调用后台代理时都会调用此方法!
这解释了我将变量视为 null 的原因,但我不明白:为什么每次都会重新创建静态类?
难道是因为后台代理位于dll项目内(需要运行它)?
有没有一种方法可以使一个仅在第一次创建的类可以在不同线程之间共享(在这种情况下它们是进程吗?)?