I have a simple program that simulates my error situation. I have a singleton class that gets a messages from several threads. The execution must be blocked until the function is executed.
class Program
{
private static TestClass test;
static void Main(string[] args)
{
Thread a = new Thread(TestFunctionB);
a.Start();
Thread b = new Thread(TestFunctionB);
b.Start();
}
private static void TestFunctionB()
{
TestClass test = TestClass.Instance;
for (int i = 0; i < 15; i++)
{
test.Handle(i, Thread.CurrentThread.ManagedThreadId);
}
}
}
class TestClass
{
private readonly object _lockObject;
private static TestClass _instance;
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get { return _instance ?? (_instance = new TestClass()); }
}
private void RunLocked(Action action)
{
lock (_lockObject)
{
action.Invoke();
}
}
public void Handle(int counter, int threadId)
{
Console.WriteLine("\nThreadId = {0}, counter = {1}\n", threadId, counter);
RunLocked(() =>
{
Console.WriteLine("\nFunction Handle ThreadId = {0}, counter = {1}\n", threadId, counter);
for (int i = 0; i < 30; i++)
{
Console.WriteLine("Funktion Handle threadId = {0}, counter = {1}, i = {2}", threadId, counter, i);
//Thread.Sleep(100);
}
});
Console.WriteLine("\nFunction Handle free ThreadId = {0}, counter = {1}\n", threadId, counter);
}
}
`
I excpect that threads write the output one after another, but in the console the threads outputs are mixed. Is the lock statement not correct?
I don't know if it is your only problem but get { return _instance ?? (_instance = new TestClass()); } is not atomic, you may end up with more than one instance returned.
Use the Lazy<T> class to guarantee that only one instance of the singleton is created.
class TestClass
{
private readonly object _lockObject;
private readonly static Lazy<TestClass> _instance = new Lazy<TestClass>(x=> new TestClass());
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get { return _instance.Value; }
}
...
}
If you don't have access to .NET 4.0 or newer you will need to lock around your singleton creation.
class TestClass
{
private readonly object _lockObject;
private static readonly object _singletonLock = new Object();
private static TestClass _instance;
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get
{
if(_instance == null)
{
lock(_singletonLock)
{
if(_instance == null)
{
_instance = new TestClass ();
}
}
}
return _instance;
}
}
...
}
Related
I have a class like this:
class Test {
const int capacity = 100_0000;
private HashSet<int> set = new HashSet<int>(capacity);
public Test() { this.Reassign(); }
private void Reassign() {
var thread = new Thread(() => {
while (true) {
set = new HashSet<int>(capacity);
Thread.Sleep(10);
}
});
thread.Start();
}
public void Add(int val) {
set.Add(val);
}
}
The add method is frequently called.
var test = new Test();
Task.Run(() => {
for (int i = 0; i < 100000000; i++) {
test.Add(i);
Thread.SpinWait(5000);
}
});
It doesn't matter whether the data is successfully stored in the set, in this case, is the behavior of the add method consistent with the following code?
class LockTest {
const int capacity = 100_0000;
private HashSet<int> set = new HashSet<int>(capacity);
public LockTest() { this.Reassign(); }
private void Reassign() {
var thread = new Thread(() => {
while (true) {
lock (set) set = new HashSet<int>(capacity);
Thread.Sleep(10);
}
});
thread.Start();
}
public void Add(int val) {
lock (set) set.Add(val);
}
}
In my tests, even if there is no lock statement, there is no error. But I don't know what happens at the moment of set = new HashSet<int>(capacity);.
If you change the code to this, what do you think will happen? My guess is that the number you print out will sometimes be the same and other time different. When it is the same, lock(set) has worked, but otherwise it hasn't.
class LockTest {
const int capacity = 100_0000;
private int setCnt = 0;
private object set = new object();
public LockTest() { this.Reassign(); }
private void Reassign() {
var thread = new Thread(() => {
while (true) {
lock (set) setCnt++;
Thread.Sleep(10);
}
});
thread.Start();
}
public void Add(int val) {
lock (set) Console.WriteLine($"{setCnt}");
}
}
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();
}
}
Scenario, I am having multiple threads trying to sharing a static global variable counter.
After which I would add it into a List of integers and this list would be used in another thread to check out some details.
I realized after even using LOCK on the global variable counter, I still get duplicate numbers
Please pardon my explanation, codes would speak more.
Problem would be different threads may be generated a same counter value( which I don't want).
I want a running number without duplicates
class Test
{
private Object _thisLock = new Object();
List<int> listing = new List<int>(); //shared LIST
public void Main()
{
//array of threads
for (int i = 0; i < 8; i++)
{
Thread th = new Thread(Work);
th.Name = "Thread" + i;
th.Start();
}
Thread.Sleep(5000);
//Start checking for duplicates
Thread checker = new Thread(Checker);
checker.Start();
}
private void Work()
{
Object _thisLock = new Object();
while (true)
{
int a = Singleton.Instance.Counter++;
Console.WriteLine(Thread.CurrentThread.Name);
Console.WriteLine("WOrk : " + a);
lock (_thisLock)
{
listing.Add(a);
}
Thread.Sleep(1000);
}
}
private void Checker()
{
Object _thisLock = new Object();
while (true)
{
lock (_thisLock)
{
List<int> selflist = new List<int>();
selflist.AddRange(listing); ;
foreach (int p in selflist)
{
if (selflist.FindAll(item => item.Equals(p)).Count() > 1)
{
Console.WriteLine("Check!!!!!!!!!!!!!!!!!! : " + p);
}
}
}
Thread.Sleep(5000);
}
}
}
static void Main()
{
Test t = new Test();
t.Main();
}
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private readonly Object _thisLock = new Object();
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
private volatile static int _counter;
public int Counter
{
get
{
lock (_thisLock)
{
return _counter;
}
}
set
{
lock (_thisLock)
{
_counter = value;
}
}
}
}
In your Work method every thread have it's own lock object _thisLock.
Remove this statement in your work method and let it use private lockobject of the class:
Object _thisLock = new Object();
Why not just move the counter into the lock and make the lock shared by moving it to the class level?
private object _thisLock = new object();
...
lock (_thisLock)
{
int a = Singleton.Instance.Counter++;
listing.Add(a);
}
Also, use a thread safe collection type, like ConcurrentBag.
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() { }
}
}
I have one thread, that is sending data stored in a buffer of type List< string> via tcp. Another thread is writing into the buffer. As I am not very familiar with c# I'd like to know how I should use lock or Mutex correctly.
This is the code I'd like to use eventually:
while(buffer.isLocked())
{
buffer.wait();
}
buffer.lockBuffer();
buffer.add(tcpPacket);
buffer.unlockBuffer();
buffer.notify();
This is my current code. I hope someone can help me complete it.
public class Buffer
{
private Mutex mutex;
private List<string> buffer;
private bool locked = false;
public Buffer()
{
mutex = new Mutex(false);
buffer = new List<string>();
}
public bool isLocked()
{
return locked;
}
public void lockBuffer()
{
if (!locked)
{
//...
locked = true;
}
}
public void unlockBuffer()
{
if(locked)
{
mutex.ReleaseMutex();
locked = false;
}
}
public void wait()
{
mutex.WaitOne();
}
public void notify()
{
//...
}
}
It would be better if you use System.Collections.Concurrent.BlockingCollection. It doesn't require an external sync.
For those who don't use 4.0
using System;
using System.Collections.Generic;
using System.Threading;
namespace MyCollections
{
public class BlockingQueue<T> : IDisposable
{
Queue<T> _Queue = new Queue<T>();
SemaphoreSlim _ItemsInQueue = null;
SemaphoreSlim _FreeSlots = null;
int _MaxItems = -1;
public BlockingQueue(int maxItems=Int32.MaxValue)
{
_MaxItems = maxItems;
_ItemsInQueue = new SemaphoreSlim(0, maxItems);
_FreeSlots = new SemaphoreSlim(maxItems, maxItems);
}
public void Dispose()
{
if (_ItemsInQueue != null) _ItemsInQueue.Dispose();
if (_FreeSlots != null) _FreeSlots.Dispose();
}
public int Count
{
get { return _ItemsInQueue.CurrentCount; }
}
public void Add(T item)
{
if(_MaxItems != Int32.MaxValue) _FreeSlots.Wait();
lock (this)
{
_Queue.Enqueue(item);
_ItemsInQueue.Release();
}
}
public T Take()
{
T item = default(T);
_ItemsInQueue.Wait();
lock (this)
{
item = _Queue.Dequeue();
if (_MaxItems != Int32.MaxValue) _FreeSlots.Release();
}
return item;
}
}
}
The following code is not thread-safe. If two threads are entering this method at the same time, both might pass the if condition successfully.
public void lockBuffer()
{
if (!locked)
{
//...
locked = true;
}
}
You simply might want to do something like this:
lock (_sycnObject)
{
buffer.lockBuffer();
buffer.add(tcpPacket);
buffer.unlockBuffer();
buffer.notify();
}
I don't think you're doing something sophisticated that requires more than the simple to use lock-statement.
I wouldn't use Mutexes since I suppose you aren't dealing with multiple processes synchronization. Locks are pretty fine and simpler to implement:
class Buffer
{
private readonly object syncObject = new object();
private readonly List<string> buffer = new List<string>();
public void AddPacket(string packet)
{
lock (syncObject)
{
buffer.Add(packet);
}
}
public void Notify()
{
// Do something, if needed lock again here
// lock (syncObject)
// {
// Notify Implementation
// }
}
}
The usage is obviously (as you requested):
var myBuffer = new Buffer();
myBuffer.Add("Hello, World!");
myBuffer.Notify();