У меня здесь немного головной уборщик, и мне интересно, может ли кто-нибудь узнать ответ.Static Variable Null In Method Call, но инициализирован в программе
Установка в основном это:
//in Visual Studio plug-in application
SpinUpProgramWithDebuggerAttached();
//in spun up program
void Start()
{
StaticClass.StaticVariable = "I want to use this.";
XmlSerializer.Deserialize(typeof(MyThingie), "xml");
}
class MyThingie : IXmlSerializable
{
ReadXml()
{
//why the heck is this null?!?
var thingIWantToUse = StaticClass.StaticVariable;
}
}
Проблема, которую я потянув меня за волосы, что StaticClass.StaticVariable является недействительным в IXmlSerializable.ReadXml() метод, даже если он вызывается сразу после переменной установлен.
Следует отметить, что точки останова не пострадали, а Debugger.Launch() игнорируется в точном месте, когда проблема возникает.
Загадочно, я определил путем создания исключений, что свойство AppDomain.CurrentDomain.FriendlyName одинаково для места, где статическая переменная заполняется против нуля!
Почему heck - это статическая переменная из сферы?!? Что происходит?!? Как я могу поделиться своей переменной?
EDIT:
Я добавил статический конструктор, за предложением в ответах, и она была сделать Debug.WriteLine. Я заметил, что он вызывается дважды, хотя весь код работает в том же AppDomain. Вот то, что я вижу в окне вывода, который я надеюсь, будет полезной подсказкой:
Статический конструктор вызывается в: 2015-01-26T13: 18: 03.2852782-07: 00
. ..Loaded 'C: ... \ GAC_MSIL \ System.Numerics \ v4.0_4.0.0.0__b77a5c561934e089 \ System.Numerics.dll' ...
... Loaded 'Microsoft.GeneratedCode' ...
... Loaded 'C: ... \ GAC_MSIL \ System.Xml.Linq \ v4.0_4.0.0.0__b77a5c561934e089 \ System.Xml.Linq.dll' ....
... Загружено 'C: \ USERS ... \ APPDATA \ LOCAL \ MICROSOFT \ VISUALSTUDIO \ 12.0EXP \ EXTENSIONS ... SharePointAdapter.dll'. Загружены символы.
... Загружено «Microsoft.GeneratedCode».
Статический конструктор вызывается в: 2015-01-26T13: 18: 03.5196524-07: 00
ДОПОЛНИТЕЛЬНЫЕ ДЕТАЛИ:
Вот фактический код, так как пару комментаторам думал, что это могло бы помочь :
//this starts a process called "Emulator.exe"
var testDebugInfo = new VsDebugTargetInfo4
{
fSendToOutputWindow = 1,
dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess,
bstrArg = "\"" + paramPath + "\"",
bstrExe = EmulatorPath,
LaunchFlags = grfLaunch | (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd | (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_WaitForAttachComplete,
dwDebugEngineCount = 0,
guidLaunchDebugEngine = VSConstants.CLSID_ComPlusOnlyDebugEngine,
};
var debugger = Project.GetService(typeof(SVsShellDebugger)) as IVsDebugger4;
var targets = new[] { testDebugInfo };
var processInfos = new[] { new VsDebugTargetProcessInfo() };
debugger.LaunchDebugTargets4(1, targets, processInfos);
//this is in the emulator program that spins up
public partial class App : Application
{
//***NOTE***: static constructors added to static classes.
//Problem still occurs and output is as follows (with some load messages in between):
//
//MefInitializer static constructor called at: 2015-01-26T15:34:19.8696427-07:00
//ContainerSingleton static constructor called at: 2015-01-26T15:34:21.0609845-07:00. Type: SystemTypes.ContainerSingleton, SystemTypes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=...
//ContainerSingleton static constructor called at: 2015-01-26T15:34:21.3399330-07:00. Type: SystemTypes.ContainerSingleton, SystemTypes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=...
protected override void OnStartup(StartupEventArgs e)
{
//...
//initializes a MEF container singleton (stored as static variable)
MefInitilizer.Run();
//here's where it blows up. the important details are that
//FullSelection implements IXmlSerializable, and its implemention
//ends up referencing the MEF container singleton, which ends up
//null, even though it was initialized in the previous line.
//NOTE: the approach works perfectly under a different context
//so the problem is not the code itself, per se, but a problem
//with the code in the environment it's running in.
var systems = XmlSerialization.FromXml<List<FullSelection>>(systemsXml);
}
}
public static class MefInitilizer
{
static MefInitilizer() { Debug.WriteLine("MefInitializer static constructor called at: " + DateTime.Now.ToString("o")); }
public static void Run()
{
var catalog = new AggregateCatalog();
//this directory should have all the defaults
var dirCatalog = new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
//add system type plug-ins, too
catalog.Catalogs.Add(dirCatalog);
var container = new CompositionContainer(catalog);
ContainerSingleton.Initialize(container);
}
}
public class ContainerSingleton
{
static ContainerSingleton()
{
Debug.WriteLine("ContainerSingleton static constructor called at: " + DateTime.Now.ToString("o") + ". Type: " + typeof(ContainerSingleton).AssemblyQualifiedName);
}
private static CompositionContainer compositionContainer;
public static CompositionContainer ContainerInstance
{
get
{
if (compositionContainer == null)
{
var appDomainName = AppDomain.CurrentDomain.FriendlyName;
throw new Exception("Composition container is null and must be initialized through the ContainerSingleton.Initialize()" + appDomainName);
}
return compositionContainer;
}
}
public static void Initialize(CompositionContainer container)
{
compositionContainer = container;
}
}
Мы не можем ответить на это с помощью данной информации. Это не отображает вашу ситуацию, поэтому в лучшем случае мы можем дать вам ответ «yup, выглядит странно». Покажите цепочку вызовов методов и как эти фрагменты относятся к eachother. –
Либо Visual Studio, либо WinDbg должны предоставить вам хотя бы стек вызовов при вызове исключения. С объемом информации, которую вы предоставили, это не отвечает ... Обратите внимание, что, вероятно, есть способы избежать статических полей (но это должен быть отдельный вопрос). –
Если это один и тот же объект AppDomain и статический конструктор, который вызывается дважды, это означает, что у вас на самом деле есть 2 типа - дамп подробной информации о самом типе ('typof (StaticClass) .FullName' может быть достаточно), чтобы убедиться, что это так. –