Ich habe ein bisschen Kopf-Scratcher hier, dass ich frage mich, ob jemand die Antwort wissen kann.Statische Variable Null In Methode Call, aber in Programm initialisiert
Das Setup ist im Grunde diese:
//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;
}
}
Das Problem, das ich mir die Haare aus hat ziehen ist, dass StaticClass.StaticVariable im IXmlSerializable.ReadXml null ist() -Methode, obwohl es direkt nach der Variable genannt ist eingestellt.
Beachten Sie, dass Haltepunkte nicht getroffen werden und Debugger.Launch() an der genauen Stelle ignoriert wird, an der das Problem auftritt.
Mysteriös, ich festgestellt, durch Auslösen von Ausnahmen, dass die AppDomain.CurrentDomain.FriendlyName -Eigenschaft ist das gleiche für die Stelle, die die statische Variable bevölkert vs. null ist!
Warum zum Teufel ist die statische Variable außerhalb des Umfangs?!? Was ist los?!? Wie kann ich meine Variable teilen?
EDIT:
Ich habe einen statischen Konstruktor, pro einem Vorschlag in den Antworten, und es hatte eine Debug.WriteLine zu tun. Ich habe bemerkt, dass es zweimal aufgerufen wurde, obwohl der gesamte Code in derselben AppDomain ausgeführt wird. Hier ist, was ich im Ausgabefenster sehen, was ich hoffe, wird ein nützlicher Hinweis sein:
Statische Konstruktor aufgerufen am: 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' ....
... Geladen 'C: \ BENUTZER \ APPDATA \ LOCAL \ MICROSOFT \ VISUALSTUDIO \ 12.0EXP \ EXTENSIONS ... SharePointAdapter.dll'. Symbole geladen.
... Geladen "Microsoft.GeneratedCode".
Statische Konstruktor aufgerufen am: 2015-01-26T13: 18: 03.5196524-07: 00
ZUSÄTZLICHE DETAIL:
Hier ist der eigentliche Code, seit ein paar commen dachte, es könnte helfen :
//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;
}
}
Wir können dies mit den gegebenen Informationen nicht beantworten. Dies zeigt Ihre Situation nicht so gut an, wir können Ihnen eine "yup, sieht komisch" -Antwort geben. Zeigen Sie die Kette von Methodenaufrufen und wie diese Snippets miteinander verknüpft sind. –
Entweder Visual Studio oder WinDbg sollten Sie mindestens Call-Stack geben, wenn eine Ausnahme ausgelöst wird. Mit der Menge an Informationen, die Sie bereitgestellt haben, ist dies nicht beantwortbar ... Beachten Sie, dass es wahrscheinlich Möglichkeiten gibt, statische Felder zu vermeiden (aber es sollte eine separate Frage sein). –
Wenn es die gleiche AppDomain und statischen Konstruktor zweimal aufgerufen wird, bedeutet das, dass Sie tatsächlich 2 Typen haben - dumpen detaillierte Informationen über den Typ selbst ('typof (StaticClass) .FullName' kann ausreichen), um zu sehen, ob dies der Fall ist. –