How can we create a Singleton Instance for a Window? - c#

I have searched for creating a Singleton object for a window in WPF.
public static Test DefInstance
{
get
{
if (formDefInstance == null) // formDefInstance.IsDisposed
{
initializingDefInstance = true;
formDefInstance = new cas18();
initializingDefInstance = false;
}
return formDefInstance;
}
set { formDefInstance = value; }
}
But the forDefInstance.IsDisposed is not working and throwing an error.
Any Idea regarding this?

I think everyone should take a look at Jon Skeet's C# In Depth site. If only to read and permanently burn into their brains the singleton patter a-la C#.
http://csharpindepth.com/Articles/General/Singleton.aspx
In your scenario, try to implement this (thread safe, non-lazy):
public sealed class DefInstance
{
private static readonly DefInstance instance = new DefInstance();
static DefInstance()
{
}
private DefInstance()
{
}
public static DefInstance Instance
{
get
{
return instance;
}
}
}
There are also Lazy<T> implementions and various other implementations of the pattern in that site.

I don't know if it's what you want to do but it works for me :
private static MyWindow _defInstance;
public static MyWindow DefInstance
{
get
{
if (null == _defInstance)
{
_defInstance = new MyWindow();
}
return _defInstance;
}
}
In MyWindow code :
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
this.Visibility = Visibility.Hidden;
e.Cancel = true;
}
To use it :
DefInstance.Show();
Then, only one window is display and you use one instance of your window.

you can achieve this by implementing following method
private static volatile DefInstance instance;
private static object syncRoot = new Object();
private DefInstance() {}
public static DefInstance Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new DefInstance();
}
}
return instance;
}
}

Related

Accessing a Singleton returns (NullReferenceException)

i feel stupid really, but i think i am being snow blind. i cannot access a singleton class method when calling from another classy. i get the dreaded
(NullReferenceException).
here are both my simple singleton and how i am calling the method.
public class PlayerNodePosition : MonoBehaviour
{
public static PlayerNodePosition instance;
string code;
void Awake()
{
if (instance == null)
{
Debug.LogWarning("More than one instance of Inventory found!");
return;
}
instance = this;
}
public void AddCode(string _code)
{
code = _code;
}
}
and here is the caller from another script.
void AddCode()
{
PlayerNodePosition.instance.AddCode("Added!");
}
being a "simpleton" i am obviously missing the obvious.
You don't instantiate instance anywhere. You would need something like
private static PlayerNodePosition playerNodePosition;
public static PlayerNodePosition instance
{
get
{
if (playerNodePosition == null) {
playerNodePosition = new PlayerNodePosition();
}
return playerNodePosition;
}
}
The method Awake should be static and the instance should be set. I have no chance to check whether this runs as I have no C# installed, but the Debug log warning you give is logically wrong. If there is no instance, you need to create one. If there is an instance, you return that one. This is the singleton pattern.
public class PlayerNodePosition : MonoBehaviour
{
public static PlayerNodePosition instance;
string code;
void static getInstance()
{
if (instance == null)
{
instance = new PlayerNodePosition();
}
return instance;
}
public void AddCode(string _code)
{
code = _code;
}
}

Static class / Object? How to dispose

i'm really struggeling with OOP. I would like to start a process in my additional class. The process is a shell and I need to access this shell from severel forms and classes to write the commands and to receive the output. I use events to get the data. Here is my class for the process.
My class for the
public class ADBShell
{
public static string output = String.Empty;
public static Process adbshell = new Process();
public void Start_ADBShell()
{
if (adbshell != null && !adbshell.HasExited)
return;
adbshell = new Process();
adbshell.StartInfo.UseShellExecute = false;
adbshell.StartInfo.FileName = #"D:\adb\adb.exe";
adbshell.StartInfo.Arguments = "shell";
adbshell.StartInfo.RedirectStandardOutput = true;
adbshell.StartInfo.RedirectStandardInput = true;
//adb.StartInfo.RedirectStandardError = true;
adbshell.EnableRaisingEvents = true;
adbshell.StartInfo.CreateNoWindow = true;
//adb.ErrorDataReceived += new DataReceivedEventHandler(adb_ErrorDataReceived);
adbshell.OutputDataReceived += new DataReceivedEventHandler(adbshell_OutputDataReceived);
try { var started = adbshell.Start(); }
catch (Exception ex)
{
Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
}
//adb.BeginErrorReadLine();
adbshell.BeginOutputReadLine();
}
void adbshell_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
output += (e.Data) + Environment.NewLine;
}
public void press_touch(string x, string y)
{
adbshell.StandardInput.WriteLine("input tap " + String.Format("{0} {1}", x, y));
Debug.WriteLine("pressed");
}
}
My Form class looks like
public partial class Form1 : Form
{
private bool _record;
private bool _selecting;
private Rectangle _selection;
//---------------------------------------------------------------------
public Form1()
{
InitializeComponent();
}
//---------------------------------------------------------------------
private void Form1_Load(object sender, System.EventArgs e)
{
ADBShell adbshell = new ADBShell();
adbshell.Start_ADBShell();
}
Everytime I have to make a new object in my methods, but i dont want to create everytime a new object. I would like make one time the object and access everytime to the same object. I do not want to make servel processes. I need only proccess and send and receive everytime the data to this process.
Do I have to make a static class?
How I can dispose and close my process after I'm quit my Form Class?
1: You do not want a static class. You want a SINGLETON - that is a class that has only one instance. This is normally accessed using a static property. At the easiest way this works like this:
public class A () {
private A () {}
public static A Instance {get; } = new A();
}
Access is via:
A.Instance
2: You do not. Processes do not get disposed. You exit the last thread that is not a background thread then the process ends. Otherwise you kill it, if that has to be done "In force" from the outside.
Move the ADBShell intialization in constructor of Form class. So this object will live till Form is not exited and to release resources by process make sure you call Process.close() in ADBShell class (Either in destructor or implement a IDisposable)
public partial class Form1 : Form
{
private bool _record;
private bool _selecting;
ADBShell adbshell;
private Rectangle _selection;
//---------------------------------------------------------------------
public Form1()
{
InitializeComponent();
adbshell = new ADBShell();
}
//---------------------------------------------------------------------
private void Form1_Load(object sender, System.EventArgs e)
{
adbshell.Start_ADBShell();
}
Dipose Process like this by adding Destructor
~ADBShell()
{
process.Close();
}
or implement Dispose method of IDisposable
Class ABDShell : IDisposable
{
...
...
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
process.Close();
}
}
}
Updated singleton class
sealed class ADBShell
{
public static string output = String.Empty;
private ABDShell _instance;
private Process _processInstance;
// Note: constructor is 'private'
private ADBShell()
{
}
public Process ProcessInstance
{
if(_processInstance==null)
_processInstance = new Process();
get _processInstance ;
}
public static ADBShell Instance
{
get
{
if (_instance == null)
{
_instance = new ABDShell();
}
return _instance;
}
}
}
Now from your Form just do this
Process process = ABDShell.Instance.ProcessInstance;
// Sealed class makes sure it is not inherited. If inheritance required, go to Abstract Pattern.
class ADBShell
{
//public static property used to expose Singleton instance.
public static ADBShell Instance;
// private constructor
private ADBShell() { }
public static ADBShell getInstance()
{
if (Instance == null)
{
Instance = new Process;
}
}
}
Update
Thank you with your helps I solved my problems and now the ADB runs much faster instead of start everytime a new process.
public class ADBShell
{
private static ADBShell instance;
//private List<Employee> employeeList = null;
private Process shell = null;
private StreamWriter myWriter = null;
private static readonly object syncRoot = new object();
private ADBShell()
{
if (shell == null)
{
shell = new Process();
shell.StartInfo.FileName = (#"D:\ADB\ADB.exe");
shell.StartInfo.Arguments = "shell";
shell.StartInfo.RedirectStandardInput = true;
shell.StartInfo.UseShellExecute = false;
shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
shell.StartInfo.RedirectStandardOutput = true;
shell.StartInfo.CreateNoWindow = true;
shell.EnableRaisingEvents = true;
shell.OutputDataReceived += (sender, a) => Console.WriteLine(a.Data);
shell.Start();
myWriter = shell.StandardInput;
shell.BeginOutputReadLine();
}
}
public static ADBShell Instance()
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new ADBShell();
}
}
}
return instance;
}
public void tap(int x, int y)
{
myWriter.WriteLine("input tap {0} {1}", x.ToString(), y.ToString());
Thread.Sleep(10);
}
public void tap(string x, string y)
{
myWriter.WriteLine("input tap {0} {1}", x, y);
Thread.Sleep(10);
}
public void exit()
{
myWriter.WriteLine("exit");
}
public void Close()
{
myWriter.WriteLine("exit");
shell.WaitForExit();
if (!shell.HasExited)
{
shell.Kill();
}
shell.Close();
shell.Dispose();
myWriter.Close();
myWriter.Dispose();
}
}

Singleton with ObservableCollection as a member

i have this ObservableCollection<MyData> list that i want to insert inside my Singleton:
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
public static ObservableCollection<MyData> list {get; set;}
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
list = new ObservableCollection<MyData>();
}
}
}
return instance;
}
}
}
Is this the This is the right way to define it ?
I don't think it is. If the ObservableCollection should be a member of the Singleton class, instantiate it in the Singleton's private constructor. If it shouldn't, I don't see why you doing it this way. What happens when you call Singleton.list BEFORE Singleton.Instance? NullReferenceException. And since its setter is public, it can be set from outside as well which is probably not what you want.
I would modify your code like this:
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
public ObservableCollection<MyData> list {get; private set;}
private Singleton() {
list = new ObservableCollection<MyData>();
}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}

global "class object" or global "server object"

I am doing a project including a custom OPC Client.
The Class Main represents the MainWindow in a WPF application.
The private field _opcServer will hold an object for further use.
Only one _opcServer object is allowed at any time.
I came up with this (it's all sample code and works fine)
// "Main" Class --> it's a WPF Window
public class Main
{
// the "global" server object
private OpcServer _opcServer = new OpcServer();
public Main() {}
private void connectOpcServer()
{
if(this._opcServer == null)
{
// the "global" server object
this._opcServer = this.opcClientFactory().connectOpcServer("someOpcServer");
if(this._opcServer != null)
{
// we made the connection
}
else
{
// connection failed
}
}
}
private void disconnectOpcServer()
{
if(this._opcServer != null)
{
if(this.opcClientFactory().disconnectOpcServer(this._opcServer))
{
// disconnected
this._opcServer = null;
}
else
{
// something went wrong
}
}
}
private OpcClient ocpClientFactory()
{
OpcClient opcClient = new opcClient();
return opcClient;
}
}
// Client Class
public class OpcClient
{
// the server object
private OpcServer _opcServer = new OpcServer();
public OpcClient() {}
public OpcServer connectOpcServer(string progID)
{
bool madeConnection = this._opcServer.Connect(progID);
if(madeConnection)
{
return this._opcServer;
}
else
{
return null;
}
}
public bool disconnectOpcServer(OpcServer opcServer)
{
this._opcServer = opcServer;
if(this._opcServer.disconnect())
{
this._opcServer = null;
return true;
}
return false;
}
}
Not much comments in the code but I think you get the point.
Every time connect or disconnect is triggered via user action, a new object of the OPC Client is created and the Server Object is passed in the one or the other direction.
There will be more methods (like read tags, etc ...) like this, but since the user should use them only once or twice per day, I see no problem with creating new objects and passing something between them.
But what if there is a real funny user who thinks he has to use these things (connect/disconnect/ etc...) all the time. Then I will end up creating many objects!
I gave it a thought and came up with this.
public class Main
{
// the client object
private OpcClient _opcClient = OpcClient.Instance;
public Main(){}
private void connectOpcServer()
{
if(this._opcClient.connectOpcServer("someOpcServer"))
{
// we made the connection and can now use
// this._opcClient.opcServer
}
else
{
// connection failed
}
}
private void disconnectOpcServer()
{
if(this._opcClient.disconnect())
{
// disconnected
}
else
{
// something went wrong
}
}
}
public class OpcClient
{
private static OpcClient _instance;
public static OpcClient Instance
{
get
{
if(instance == null)
{
_instance = new OpcClient();
}
return _instance;
}
}
private OpcClient()
{
this.opcServer = new OpcServer();
}
public OpcServer opcServer
{
get;
private set;
}
public bool connectOpcServer(string progID)
{
return this.opcServer.Connect(progID);
}
public bool disconnectOpcServer()
{
return this.opcServer.disconnect();
}
}
Now I create a singelton of the OPC Client and pass it to the main class. Now only one object will be created, the user can click connect/disconnect all day long.
What is the best way to proceed here?
Store the Server Object in the main class
Store the Class Object in the main class
Depends
Both are bad ideas (if so, why? What can I do instead?)
I am choosing the 2nd option.
By choosing the singleton approach I can make sure that there is only one Server Object.
This is very important.

Common Pattern to Initialize A Singleton On A Background Thread

I currently have a singleton, which can take up to 10 seconds to initialize. However, I don't want my users to penalized (waiting) for this initialize, so I'd rather bootstrap this component on a background thread during application startup. Here's what I have:
Singleton:
public class MySingleton
{
private static MySingleton _instance;
private static readonly object _locker = new object();
private MySingleton()
{
Init();
}
public static MySingleton Instance
{
if(_instance == null) _instance = new MySingleton();
return _instance;
}
public void Init()
{
lock(_locker)
{
if(_instance != null) return;
// long running code here...
}
}
}
Application Startup:
Task.Factory.StartNew(() => MySingleton.Instance.Init());
This code does work, guards against double init, guards against the edge case of the user needing it before it's done initializing and also guards against someone forgetting to call Init().
However, it feels a little clunky for two reasons:
a) I'm going to go into the Init method twice on startup.
b) I'd like to do threading inside the singleton, but something has to initiate the initialization.
Is there a cleaner/nicer/better way to handle this?
Thanks in advance for everyone's help.
**EDIT: As pointed out in the comments, Init was mistakenly scoped as private. It should be public and has been corrected.
Use the static constructor to trigger it and a ManualResetEvent for the syncing. It gives you a solution where everything is done within the actual class. It's therefore not dependent of that someone should call your init method.
public class MySingleton
{
private static MySingleton _instance;
private static ManualResetEvent _initEvent = new ManualResetEvent(false);
static MySingleton()
{
ThreadPool.QueueUserWorkItem(state => Init());
}
public static MySingleton Instance
{
_initEvent.Wait();
return _instance;
}
private static void Init()
{
_instance = new MySingleton();
// long running code here...
_initEvent.Set();
}
}
The event will stay signaled once triggered which means that the Instance property will return ASAP when the Init method is done.
You should define and call singleton class as below...
var instance = MySingleton.Instance;
while (true)
{
/// check for whether singleton initialization complete or not
if (MySingleton.Initialized)
{
break;
}
}
public class MySingleton
{
private static MySingleton _instance;
private static readonly object _locker = new object();
public static bool Initialized { get; set; }
private MySingleton()
{
ThreadPool.QueueUserWorkItem(call => Init());
}
public static MySingleton Instance
{
get
{
if (_instance == null)
_instance = new MySingleton();
return _instance;
}
}
private void Init()
{
lock (_locker)
{
if (Initialized)
return;
// long running code here...
for (int i = 0; i < 10000; i++)
{
}
Initialized = true;
}
}
}
I'd mybe go with a Task<T>:
class Program
{
static void Main(string[] args)
{
MySingleton.Init();
Thread.Sleep(7000);
Console.WriteLine("Getting instance...");
var mySingleton = MySingleton.Instance;
Console.WriteLine("Got instance.");
}
public class MySingleton
{
private static Lazy<MySingleton> instance;
public static MySingleton Instance
{
get { return instance.Value; }
}
public static void Init()
{
var initTask = Task.Factory.StartNew(() =>
{
for(int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Console.WriteLine("Doint init stuff {0}...", i);
}
return new MySingleton();
});
instance = new Lazy<MySingleton>(() => initTask.Result);
}
private MySingleton() { }
}
}

Categories