My Goal: I have HASP with whom I need to communicate using Serial port.
The thing is many functions from different threads may want to communicate to this HASP - and I want some synchronization to occur.
What I did: I created wrapper class called HASPClass. Looks like this:
class HASPCLass
{
SerialPort m_port;
HASPClass(..)
{
//.. Init some other properties
m_port.Open();
//..
}
void CustomWriteToHASP()
{
//.. Do something
m_port.Write(...);
}
void CustomReadHASP()
{
//.. Do something
m_port.Read(...);
}
void Close ()
{
//Some code to close m_port
};
}
Usage of this class would be:
Function1 from some thread:
HASPClass o = new HASPClass(..);
o.CustomWriteToHASP(..)
Function2 from other thread:
HASPClass o1 = new HASPClass(..);
o1.CustomReadHASP(..)
Problem1: Now if o didn't close the m_port - constructor of o1 will throw since port is open.
I want to avoid this and make o1 wait for o to finish job.
What I thought: Maybe I should make m_port static - and put static lock everywhere it is used in HASPClass, will it solve above problem? Also the constructor will be changed to only open static m_port if it is closed. Will this approach solve most of the problems I outlined before?
Update: My other problem is that different objects might specify different parameters (baud rate etc.) in constructor - so I encounter a problem :( since I have single static m_port. :(. What to do in such case?? (I could relax this requirement and say all objects will put same parameters in constructor, but will it help?)
A simple singleton pattern might look something like this:
class HASPClass
{
private static HASPClass _instance;
private HASPClass(..)
{
//.. Init some other properties
}
public static GetInstance(...)
{
// Note, if called with different parameters then this will be
// quite a bit more complicated
if (_instance == null)
{
_instance = new HASPClass(...)
}
return _instance;
}
}
Now when you call it, you'd do something like:
HASPClass o = HASPClass.GetInstance(..);
o.CustomWriteToHASP(..)
But...since you are multithreading, this pattern won't be safe. You'll need to implement some locking around the critical GetInstance section to ensure that you don't create more than one object. So you could do something like:
private static object lockObj = new object();
public static GetInstance(...)
{
// Note, if called with different parameters then this will be
// quite a bit more complicated
if (_instance == null)
{
lock (lockObj)
{
if (_instance == null)
{
_instance = new HASPClass(...)
}
}
}
return _instance;
}
Better than manually locking would be to use Lazy, but that might be complicated if you need to pass parameters. If (as I assume) those parameters are only ever passed once, you might want to have a separate initialization function that will store those parameters so you don't need to pass them when you get your instance.
If the parameters are the same every time, you could maybe try something like this:
class HASPClass
{
private static ParameterObject _parameters;
private static Lazy<HASPClass> _instance = new Lazy<HASPClass>(() =>
{
if (_parameters == null)
{
throw new InvalidOperationException("Can get instance before initializing");
}
return new HASPClass(_parameters);
});
public static HASPClass Instance
{
get { return _instance.Value; }
}
private HASPClass(ParametersObject parameters)
{
// create and populate your object using values from parameters
}
public static void Initialize(ParameterObject parameters)
{
if (_parameters != null)
{
// you might throw an exception here if this is not allowed
// Or you might drop and recreate your object if it is allowed
}
_parameters = parameters;
}
}
You may or may not need to have locking around Initialize, but the idea would be that you'd probably call Initialize first from a parent thread so that it never needs to be called again from any other thread.
class HASPCLass
{
static SerialPort m_port;
HASPClass(..)
{
lock(m_port)
{
if (!Initialized())
{
Initialize();
}
}
}
void Close ()
{
lock(m_port)
{
if (Initialized())
{
Uninitialize();
}
}
}
}
Here is one more variant of the code for you. It should work in any case. It reopens the port in case of different baud rate requested.
class HASPCLass
{
private static SerialPort m_port;
private static bool m_initialized;
private static int m_baudRate;
public HASPClass(int baudRate)
{
lock(m_port)
{
if (!m_initialized)
{
Initialize(baudRate);
}
}
}
private Initialize()
{
m_port.open(baudRate);
m_baudRate = baudRate;
m_initialized = true;
}
private Uninitialize()
{
m_port.close();
m_initialized = false;
}
private ReinitializeIfNeeded(int baudRate)
{
if (baudRate != m_baudRate)
{
Uninitialize();
Initialize(baudRate);
}
}
public void Read(int baudRate, out buff)
{
lock(m_port)
{
ReinitializeIfNeeded(baudRate);
m_port.Read(out buff);
}
}
public void Write(int baudRate, in buff)
{
lock(m_port)
{
ReinitializeIfNeeded(baudRate);
m_port.Write(buff);
}
}
public void Close()
{
lock(m_port)
{
if (m_initialized)
{
Uninitialize();
}
}
}
}
Related
Example Code (I use Semaphore rather than lock to "lock" that bool member):
public class MsgSendHandler
{
private bool _isSocketSending = false;
private Semaphore _socketSendingSem = new Semaphore(1, 1);
public void Send(INetMsg msg)
{
// Add Msg To MsgQueue
TrySendNext();
}
private void SendCallback(IAsyncResult ar)
{
// Finish Send
_socketSendingSem.WaitOne();
_isSocketSending = false;
_socketSendingSem.Release();
TrySendNext();
}
private bool TrySendNext()
{
_socketSendingSem.WaitOne();
if (_isSocketSending)
return false;
_isSocketSending = true;
_socketSendingSem.Release();
// Socket Begin Send => SendCallback
return true;
}
}
Can I "lock" a value type like this? Is there any better solution?
Expanding on comment:
The way I created mutli-threaded functionality in Unity3D was to have a Dispatcher class that is called once per frame to run any Actions that have been added to a list.
Dispatcher.cs
A simple singleton class that holds the actions with an actual lock when looping through the actions.
public class Dispatcher
{
private static Dispatcher _instance;
public static Dispatcher Instance
{
get
{
if(_instance == null)
{
_instance = new Dispatcher();
}
return _instance;
}
}
private List<Action> _actions = new List<Action> ();
public void AddAction(Action action)
{
lock (_actions)
{
_actions.Add(action);
}
}
public void CompleteActions()
{
lock (_actions)
{
foreach (Action action in _actions)
{
action();
}
}
_actions.Clear();
}
public void ClearActions()
{
lock (_actions)
{
_actions.Clear();
}
}
}
DispatcherUpdate.cs
Another simple class that's added to a GameObject within the scene to call the Dispatcher to Complete the aquired Actions.
public class DispatcherUpdate : MonoBehaviour
{
private void Awake()
{
Dispatcher.Instance.ClearActions();
}
private void Update()
{
Dispatcher.Instance.CompleteActions();
}
}
Usage
Dispatcher.Instance.AddAction(() => TrySendNext());
This is the method I've used for Async multi-threading with SignalR
I have a bit of weird problem that is hard to explain. I have singleton class where in the constructor I have to run a task to initialize some components/resources.
I used 2 implementation of singleton from C# in Depth and in one case everything is working fine, in another case - not.
Code is available below with some comments.
The main problem that for some reason task is not started in one case, when I am using static field with initialier and static contructor (class Test2).
I made some other tests and looks like with the implementation 2 task does not start asynchronically, but starts synchronically after waiting time.
Implementation one. everything is working as expected
public sealed class Test1
{
private static Test1 instance = null;
private static readonly object padlock = new object();
private Test1()
{
using (AutoResetEvent startEvent = new AutoResetEvent(false))
{
new Task(() => TaskThread(startEvent)).Start();
if (!startEvent.WaitOne(1000))
{
throw new Exception("ERROR");
}
}
}
public int Result()
{
return 10;
}
private void TaskThread(AutoResetEvent startEvent)
{
//I am initializing some stuff here
startEvent.Set();
}
public static Test1 Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Test1();
}
return instance;
}
}
}
}
Implementation 2, task is never started, or started after waiting time of an event
public sealed class Test2
{
private static readonly Test2 instance = new Test2();
static Test2()
{
}
private Test2()
{
using (AutoResetEvent startEvent = new AutoResetEvent(false))
{
new Task(() => TaskThread(startEvent)).Start();
//here it fails to wait successfully and throws an
//exception. Time limit is not reached
if (!startEvent.WaitOne(1000))
{
throw new Exception("ERROR");
}
}
}
public int Result()
{
return 20;
}
private void TaskThread(AutoResetEvent startEvent)
{
//I am initializing some stuff here as well
//but in this implementation code is never reached
startEvent.Set();
}
public static Test2 Instance
{
get
{
return instance;
}
}
}
I am curious why is this happening and how to avoid this problems in future. Thanks a lot!
The root cause of such 'strange' behavior is pretty simple - CLR executes static constructor under a lock. That prevents created thread from entering TaskThread() method and setting startEvent to signaled state.
After you face with such a problem and puzzle for several hours why this is happening, you start to understand why many sources advise not to use doubtful constructs like static constructors, global variables, etc.
I'm trying to expose an API such that, I do the following
RegisterCallback<T>(Action<T> func)
{
someObj.FuncPointer = func;
}
Later on, I call func(obj) .. and the obj is of type T that the user said.
More concrete example:
var callbackRegistrar = new CBRegistrar();
callbackRegistrar.RegisterCallback<ISomeClass>(SomeFunc);
public static void SomeFunc(ISomeClass data)
{
//
}
EDIT: So I may not have been clear, so I'll add more code:
I want to make only "one" object of CBRegistrar, and connect it with many Callbacks, as such:
var callbackRegistrar = new CBRegistrar();
callbackRegistrar.RegisterCallback<ISomeClass>(SomeFunc);
callbackRegistrar.RegisterCallback<ISomeOtherClass>(SomeFunc2);
...
In fact the above code is called by reflecting over a directory of plugins.
The user puts this in their code -->
public static void SomeFunc(ISomeClass data)
{
//
}
public static void SumFunc2(ISomeOtherClass data)
{
//
}
It looks to me as if this is not possible using Generics, etc. What it looks like I might have to do is make an interface called IPlugin or something, and ask the user to do this ..
[PluginIdentifier(typeof(ISomeClass))]
public static void SomeFunc(IPluginData data)
{
var castedStuff = data as ISomeClass; // ISomeClass inherits from IPluginData
}
Seems like asking the user to do stuff that we should take care of, but anyway ...
You need a Action<T> func to store it in. There is a semantic check to make here: if someone calls RegisterCallback twice (with different values), do you want to replace the callback, or keep both ? Assuming the latter, someObj probably wants an event (indeed, this entire API could be exposed as an event), so - in the someObj class:
public event Action<T> FuncPointer;
private void InvokeCallback(T data) {
var handler = FuncPointer;
if(handler != null) handler(data);
}
Noting that RegisterCallback could be replaced entirely, still keeping the data on obj:
public event Action<T> Completed {
add { obj.FuncPointer += value; }
remove { obj.FuncPointer -= value; }
}
Then usage would be:
var callbackRegistrar = new CBRegistrar();
callbackRegistrar.Completed += SomeFunc;
Callback functions are not much used in C#. They've been replaced by events which are more elegant and easier to work with.
class CBRegistrar
{
public delegate void ActionRequiredEventHandler(object sender, ISomeClass e);
public event ActionRequiredEventHandler ActionRequired;
void RaiseActionRequiredEvent(ISomeClass parm)
{
if ( ActionRequired != null)
{
ActionRequired(this, parm);
}
}
}
class APIConsumer
{
var callbackRegistrar = new CBRegistrar();
public APIConsumer()
{
callbackRegistrar.ActionRequired += SomeFunc;
}
public void SomeFunc(object sender, ISomeClass data)
{
}
}
If you still want to use Callbacks, you can use Delegates which are more or less function pointer.
The CBRegistrar will need to be generic (if it's OK to keep a single callback type) or it can do some internal casting (if several callback types need to be registered).
public class CBRegistrar<T>
{
private Action<T> callback;
private Dictionary<Type, object> callbackMap;
public CBRegistrar()
{
this.callbackMap = new Dictionary<Type, object>();
}
public void RegisterCallback(Action<T> func)
{
this.callback = func;
}
public void RegisterGenericCallback<U>(Action<U> func)
{
this.callbackMap[typeof(U)] = func;
}
public Action<U> GetCallback<U>()
{
return this.callbackMap[typeof(U)] as Action<U>;
}
}
public interface ISomeClass
{
string GetName();
}
public class SomeClass : ISomeClass
{
public string GetName()
{
return this.GetType().Name;
}
}
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var callbackRegistrar = new CBRegistrar<ISomeClass>();
callbackRegistrar.RegisterCallback(SomeFunc);
callbackRegistrar.RegisterGenericCallback<ISomeClass>(SomeFunc);
var someone = new SomeClass();
callbackRegistrar.GetCallback<ISomeClass>()(someone);
}
public static void SomeFunc(ISomeClass data)
{
// Do something
Console.WriteLine(data.GetName());
}
}
}
I am not sure if I understood the usage of delegates correctly but I would like to read delegate return value in publisher class. The example is below with description.
//Publisher class
public class ValidateAbuse
{
public delegate List<String> GetAbuseList();
public static GetAbuseList Callback;
public void Ip(string ip)
{
// I would like to read GetAbuseList value (List<String>) here. How to do that?
}
}
//Subscriber class
class Server
{
public static void Start()
{
ValidateAbuse.Callback = GetIpAbuseList;
ValidateAbuse.Ip(MyIp);
}
private static List<string> GetIpAbuseList()
{
//return List<String> to ValidateAbuse class and use return value in public void Ip(string ip) method
}
public void Ip(string ip)
{
if (Callback != null)
{
List<String> valueReturnedByCallback = Callback();
}
}
Here's a version that does not use static for ValidateAbuse and that uses the built-in Func<T> delegate.
public class ValidateAbuse
{
private Func<List<string>> callback;
public ValidateAbuse(Func<List<string>> callback)
{
this.callback = callback;
}
public void Ip(string ip)
{
var result = callback();
}
}
public class Server
{
public static void Start()
{
var validateAbuse = new ValidateAbuse(GetIpAbuseList);
validateAbuse.Ip(MyIp);
}
private static List<string> GetIpAbuseList()
{
//return List<string> to ValidateAbuse class and use return value in public void Ip(string ip) method
}
}
I recommend you avoid static since that gives you a global state, which could later give you coupling problems and also makes it hard for you to unit test.
The other answers given so far has a guard clause, checking Callback for null. Unless that is expected behaviour (that Callback is null) I would avoid this. It's better to crash early than to get hard to debug errors later on.
I would also try to make the Server non-static.
It should be as simple as:
// Ip in your code sample is missing static
public static void Ip(string ip)
{
List<string> abuseList;
if (Callback != null)
abuseList = Callback()
}
However you can avoid creating a delegate all together by using a Func:
public static Func<List<string>> Callback;
Try this: Read more from here http://msdn.microsoft.com/en-us/library/bb534960%28v=vs.110%29.aspx
internal delegate int PowerOfTwo();
void Main(){
PowerOfTwo ch = new PowerOfTwo(CheckPower);
Console.WriteLine(ch());
}
int CheckPower(){
return 2*2;
}
#Torbjörn Kalin's answer is good, but only if you have only 1 delegate you want to get the return value from. If you want to retrieve the return values of more than one delegate, this is how you do it:
//Publisher class
public class ValidateAbuse
{
public delegate List<String> GetAbuseList();
public static GetAbuseList Callback;
public void Ip(string ip)
{
foreach (GetAbuseList gal in Callback.GetInvocationList())
{
List<string> result = gal.Invoke(/*any arguments to the parameters go here*/);
//Do any processing on the result here
}
}
}
//Subscriber class
class Server
{
public static void Start()
{
//Use += to add to the delegate list
ValidateAbuse.Callback += GetIpAbuseList;
ValidateAbuse.Ip(MyIp);
}
private static List<string> GetIpAbuseList()
{
//return code goes here
return new List<String>();
}
This will invoke each delegate one after the other, and you can process the output of each delegate separately from each other.
The key here is using the += operator (not the = operator) and looping through the list that is retrieved by calling GetInvocationList() and then calling Invoke() on each delegate retrieved.
I figured this out after reading this page:
https://www.safaribooksonline.com/library/view/c-cookbook/0596003390/ch07s02.html
(altho it was partially because I already had an idea what to do, and I didn't start a free trial to read the rest)
Hope this helps!
Currently I have the following class:
public class PluginManager
{
private static bool s_initialized;
private static object s_lock = new object();
public static void Initialize() {
if (!s_initialized) {
lock (s_lock) {
if (!s_initialized) {
// initialize
s_initialized = true;
}
}
}
}
}
The important thing here is that Initialize() should only be executed once whilst the application is running. I thought that I would refactor this into a singleton class since this would be more thread safe?:
public sealed class PluginService
{
static PluginService() { }
private static PluginService _instance = new PluginService();
public static PluginService Instance { get { return _instance; } }
private bool s_initialized;
public void Initialize() {
if (!s_initialized)
{
// initialize
s_initialized = true;
}
}
}
Question one, is it still necessary to have the lock here (I have removed it) since we will only ever be working on the same instance?
Finally, I want to use DI and structure map to initialize my servcices so I have refactored as below:
public interface IPluginService {
void Initialize();
}
public class NewPluginService : IPluginService
{
private bool s_initialized;
public void Initialize() {
if (!s_initialized) {
// initialize
s_initialized = true;
}
}
}
And in my registry:
ForRequestedType<IPluginService>()
.TheDefaultIsConcreteType<NewPluginService>().AsSingletons();
This works as expected (singleton returning true in the following code):
var instance1 = ObjectFactory.GetInstance<IPluginService>();
var instance2 = ObjectFactory.GetInstance<IPluginService>();
bool singleton = (instance1 == instance2);
So my next question, is the structure map solution as thread safe as the singleton class (second example). The only downside is that this would still allow NewPluginService to be instantiated directly (if not using structure map).
Many thanks,
Ben
I would make several recommendations:
the boolean flag should be volatile
make your singleton instance readonly
the initialization is not thread safe, regardless of the fact that you have only one instance... so it should be synchronized
public sealded class PluginService
{
static PluginService() { }
//make the instance readonly
private static readonly PluginService _instance = new PluginService();
public static PluginService Instance { get { return _instance; } }
// make the flag volatile
private static volatile bool s_initialized = false;
private static object s_lock = new object();
// you still need to synchronize when you're initializing
public void Initialize() {
lock(s_lock)
{
if (!s_initialized)
{
// initialize
s_initialized = true;
}
}
}
}
There is no contention on the structured map, so its thread safety doesn't seem compromised...
The singleton class you had was not thread safe. The main thing to remember is that a single instance does not ensure a single thread can only access it. If there are multiple threads that have a reference to the instance, then there is contention on the instance and the data it's holding. If there is contention then you should ensure thread safety (synchronize at the very minimum).