I am working on an application in which I am getting orders from an third party app. The application is written on windows form so I am using service stack to add routes in my application.
I have three classes. One contains endpoint
public class Service : ServiceStack.Service
{
Repository _repository;
public OrderService()
{
_repository = Repository.GetInstance();
}
[Authenticate]
public void Post(Order order)
{
if (order != null)
{
_repository.AddItem(order);
}
}
}
The second class is processing the orders and this class is a singleton class.
public sealed class Repository
{
private static object _myLock = new object();
private static Repository _mySingleton = null;
private ConcurrentQueue<Order> _queue;
public static bool orderCheck = true;
private Repository() {
_queue = new ConcurrentQueue<Order>();
}
public void AddItem(Order order)
{
_queue.Enqueue(order);
}
public static Repository GetInstance()
{
if (_mySingleton == null)
{
lock (_myLock)
{
if (_mySingleton == null)
{
_mySingleton = new Repository();
}
}
}
return _mySingleton;
}
public void CreateOrder()
{
while (orderCheck)
{
Order order = null;
_queue.TryDequeue(out order);
if (order != null)
{
try
{
// performing business logic with order
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
else
{
Thread.Sleep(10000);
}
}
}
}
The third class creates a new thread when the application is started:
new Thread(delegate ()
{
var repo = Repository.GetInstance();
repo.CreateOrder();
}).Start();
The problem is that the endpoint added the order information in the queue, but when I try to dequeue in the Repository class then it's not available on the tryDequeue method.
I put the getHashCode of ConcurrentQueue and I found the hashcode showing differently in while loop and in AddItem method.
Related
I am attempting to communicate information between two different projects. One is a remoting server and the other a WPF application. I have created a singleton class but have noticed that each time one project calls the GetInstance method it creates a new instance of the singleton. Is it possible to have a singleton accross projects as it doesn't seem it is and if that is the case, why is that?
Below is my code for the singleton
public class CommunicationSingleton
{
private int jobCount = 0;
private Job jobInProgress;
private List<Job> jobs = new List<Job>();
private static CommunicationSingleton instance = new CommunicationSingleton();
static readonly object obj = new object();
private CommunicationSingleton() { }
public static CommunicationSingleton GetInstance()
{
lock (obj)
{
if (instance == null)
{
return instance = new CommunicationSingleton();
}
else
{
return instance;
}
}
}
public void AddJob(Job job)
{
jobs.Add(job);
}
public List<Job> GetJobs()
{
return jobs;
}
public void IncreaseJobCount(int jobCount)
{
this.jobCount += jobCount;
}
public int GetJobCount()
{
return jobCount;
}
public void JobInProgress(Job jobInProgress)
{
this.jobInProgress = jobInProgress;
}
public Job GetJobInProgress()
{
return jobInProgress;
}
}
i have a singleton class (MySingletonClass) that has three main methods
BeginTransaction(clientId)
AddItem(item, clientId)
CommitTransaction(clientId)
The ClientClass is:
public class ClientClass
{
private string id;
private MySingletonClass s = MySingletonClass.Instance;
public ClientClass()
{
id = new Guid().ToString();
}
public void BeginTransaction()
{
//start a lock here
s.BeginTransaction(id);
}
public void CommitTransaction()
{
s.CommitTransaction(id);
//end lock here
}
public void AddItem(string item)
{
//no access until lock is released
s.AddItem(item, id);
}
}
There are many task each of which with its own ClientClass class
I need a way to serialize access to singleton class by transaction:
if a transaction has not been committed then no other thread should start a new transaction or calla any other method on the singleton instance
For example every task can have code like this
Task.Factory.StartNew(() =>
{
Client c = new ClientClass();
c.BeginTransaction();
c.AddItem("www");
c.AddItem("qqq");
c.CommitTransaction();
});
Task.Factory.StartNew(() =>
{
Client c1 = new ClientClass();
c1.BeginTransaction();
c1.AddItem("aaa");
c1.CommitTransaction();
});
Any idea how can i archieve this with some sort of locking that starts on begin transaction and is released on commit?
All the examples i've seen of monitor , mutex and lock start and are released in the same method.
Is there a lock over multiple methods??
Your MySingletonClass could look something like this:
public class MySingletonClass {
private readonly Object _lockObject = new object();
private List<string> _list = new List<string>();
public void BeginTransaction()
{
Monitor.Enter(_lockObject);
_list.Clear();
}
public void AddItem(string item)
{
if( Monitor.IsEntered(_lockObject) == false ) throw new ThreadStateException("Not owner of transaction");
_list.Add(item);
}
public void CommitTransaction()
{
if( Monitor.IsEntered(_lockObject) == false ) throw new ThreadStateException("Not owner of transaction");
Monitor.Exit(_lockObject);
}
public void RollbackTransaction()
{
if( Monitor.IsEntered(_lockObject) == false ) throw new ThreadStateException("Not owner of transaction");
Monitor.Exit(_lockObject);
}
}
But if a ClientClass fails (exception being thrown) between BeginTransaction and CommitTransaction, it very important to call RollbackTransaction else all threads will deadlock since the monitor is never freed.
So it is not a recommendable solution.
Review the following code, where to take care of cases with both single and named binding for an interface, an abstract factory is used as suggested here
Parameterized Factories Using Ninject
Challenge here is, I need to introduce IEnumerable<T> bankingOperationList, instead of T bankingOperationList, since for named binding it will always use the abstract factory injection, Func<string,T> bankingOperationFunc, but if I don't use IEnumerable<T> suggested above it leads to exception, due to this for even non named single binding, I need to use something like:
bankingOperationList.FirstOrDefault().Withdraw(), even when I know there will only be one dependency.
Another challenge is, for some named bindings it has 30 - 40 bindings in few cases, which will be unnecessarily filled, when I can default T bankingOperationList to null, as it is not required. Please let me know, if the issue needs further clarification. Working Console project underneath.
public interface IBankingOperation
{
void Withdraw();
}
public class BankingOperationOne : IBankingOperation
{
public BankingOperationOne()
{
Console.WriteLine("Testing Constructor :: One :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation One");
}
}
public class BankingOperationTwo : IBankingOperation
{
public BankingOperationTwo()
{
Console.WriteLine("Testing Constructor :: Two :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation Two");
}
}
// Ninject Bindings
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IBankingOperation>().To<BankingOperationOne>()
.Named("A");
Bind<IBankingOperation>().To<BankingOperationTwo>()
.Named("B");
Bind<Func<string,IBankingOperation>>().ToMethod(ctx => name => ctx.Kernel.Get<IBankingOperation>(name));
}
}
public class BankTran<T> where T : IBankingOperation
{
private IEnumerable<T> bankingOperationList = null;
private Func<string,T> bankingOperationFunc;
public BankTran(IEnumerable<T> boList = null,
Func<string,T> boFunc = null)
{
bankingOperationList = boList;
bankingOperationFunc = boFunc;
}
public void DoOperation(string identifier = null)
{
if(bankingOperationFunc != null)
bankingOperationFunc(identifier).Withdraw();
else
bankingOperationList.FirstOrDefault().Withdraw();
Console.WriteLine("Transaction Successful ");
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly()); // Load from Bindings (derived from NinjectModule)
var transaction = kernel.Get<BankTran<IBankingOperation>>();
transaction.DoOperation("A");
}
}
Edit 1, based on response by jbl
public interface IBankingOperation<T>
{
void Withdraw();
}
public class BankingOperationOne : IBankingOperation<TestOne>
{
public BankingOperationOne()
{
Console.WriteLine("Testing Constructor :: One :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation One");
}
}
public class BankingOperationTwo : IBankingOperation<TestTwo>
{
public BankingOperationTwo()
{
Console.WriteLine("Testing Constructor :: Two :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation Two");
}
}
public class TestOne { }
public class TestTwo { }
// Ninject Bindings
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("A");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("B");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().WhenInjectedInto(typeof(BankTran<TestOne>));
Bind<Func<string, IBankingOperation<TestOne>>>().ToMethod(ctx => name => ctx.Kernel.Get<IBankingOperation<TestOne>>(name));
Bind<IBankingOperation<TestTwo>>().To<BankingOperationTwo>();
}
}
public class BankTran<T> where T : class
{
private IBankingOperation<T> bankingOperation;
private Func<string, IBankingOperation<T>> bankingOperationFunc;
public BankTran(IBankingOperation<T> bo = null,
Func<string, IBankingOperation<T>> boFunc = null)
{
bankingOperation = bo;
bankingOperationFunc = boFunc;
}
public void DoOperation(string identifier = null)
{
if (bankingOperationFunc != null && identifier != null)
bankingOperationFunc(identifier).Withdraw();
else if (bankingOperation != null)
bankingOperation.Withdraw();
Console.WriteLine("Transaction Successful ");
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel(new NinjectSettings { AllowNullInjection = true});
kernel.Load(Assembly.GetExecutingAssembly()); // Load from Bindings (derived from NinjectModule)
var transaction = kernel.Get<BankTran<TestOne>>("A"); // Not Working
// var transaction = kernel.Get<BankTran<TestOne>>(); // Working
transaction.DoOperation();
}
}
Assuming BankingOperationOne is your default behaviour,
adding the following line in your Load method should allow to replace the IEnumerable<T> with T in your BankTran constructor :
Bind<IBankingOperation>().To<BankingOperationOne>().WhenInjectedInto(typeof(BankTran<>));
Another solution would be to just define a named binding for default behaviour
Bind<IBankingOperation>().To<BankingOperationOne>().Named("__DefaultBehaviour");
then
public void DoOperation(string identifier = "__DefaultBehaviour")
{
if (bankingOperationFunc != null)
bankingOperationFunc(identifier).Withdraw();
Console.WriteLine("Transaction Successful ");
}
Edit :
You should use the Ninject.Extenstions.Factory nuget package.
Using this package, the following code seems to fullfill you requirements.
public interface IBankingOperation<T>
{
void Withdraw();
}
public interface IBankingOperationFactory<T>
{
IBankingOperation<T> GetBankingOperation(string name);
}
public class BankingOperationOne : IBankingOperation<TestOne>
{
public BankingOperationOne()
{
Console.WriteLine("Testing Constructor :: One :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation One");
}
}
public class BankingOperationTwo : IBankingOperation<TestTwo>
{
public BankingOperationTwo()
{
Console.WriteLine("Testing Constructor :: Two :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation Two");
}
}
public class TestOne { }
public class TestTwo { }
// Ninject Bindings
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("A");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("B");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().WhenInjectedInto(typeof(BankTran<TestOne>));
Bind<IBankingOperationFactory<IBankingOperation<TestOne>>>().ToFactory();
Bind<IBankingOperation<TestTwo>>().To<BankingOperationTwo>();
}
}
public class BankTran<T> where T : class
{
private IBankingOperation<T> bankingOperation;
private IBankingOperationFactory<T> _bankingOperationFactory;
public BankTran(IBankingOperation<T> bo = null,
IBankingOperationFactory<T> bankingOperationFactory = null)
{
bankingOperation = bo;
_bankingOperationFactory = bankingOperationFactory;
}
public void DoOperation(string identifier = null)
{
if (_bankingOperationFactory != null && identifier != null)
_bankingOperationFactory.GetBankingOperation(identifier).Withdraw();
else if (bankingOperation != null)
bankingOperation.Withdraw();
Console.WriteLine("Transaction Successful ");
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel(new NinjectSettings { AllowNullInjection = true });
kernel.Load(Assembly.GetExecutingAssembly()); // Load from Bindings (derived from NinjectModule)
var transaction = kernel.Get<BankTran<TestOne>>();
transaction.DoOperation();
transaction.DoOperation("A");
transaction.DoOperation("B");
}
}
public class RefDataProvider : IRefDataProvider
{
private const string REF_DATA_COUNTRIES = "CountryData";
public IEnumerable<CountryLookupDto> GetCountries()
{
//if in cache then get cached version
if (CacheManager.GetInstance.OCache.Contains(REF_DATA_COUNTRIES))
return CacheManager.GetInstance.GetTypedItem<IEnumerable<CountryLookupDto>>(REF_DATA_COUNTRIES);
//not in cache so get from dadtavase
using (var service = new CrmServiceClient())
{
try
{
IEnumerable<CountryLookupDto> countriesDto = service.LookupCountries("*");
bool addedToCache = CacheManager.GetInstance.AddItemWithExpiration(REF_DATA_COUNTRIES, countriesDto,
12);
if (!addedToCache) throw new Exception("Cannot add ref data to cache");
}
catch (Exception ex)
{
LoggingManager.GetInstance.Log("Error", ex, LoggingManager.LogLevel.Error);
throw;
}
finally
{
service.Close();
}
}
return CacheManager.GetInstance.GetTypedItem<IEnumerable<CountryLookupDto>>(REF_DATA_COUNTRIES);
}
}
Trying to do unit test onto the method. Having problem with wcf client call.
I am trying to verify CrmServiceClient() calls in unit test. Is there any way to test wcf calls in unit test. Please advise.
[TestFixture]
public class TestRefDataProvider
{
private IReferenceDataProvider _referenceDataProvider;
[SetUp]
public void SetUp()
{
_referenceDataProvider = new ReferenceDataProvider();
}
[Test]
public void Verify_GetCountries()
{
Assert.IsNotNull(_referenceDataProvider.GetCountries());
}
}
Thanks Ilya. After Ilya explains: I came out with this:
public class ReferenceDataProvider : IReferenceDataProvider
{
private const string REF_DATA_TITLE = "TitleData";
private const string REF_DATA_COUNTRIES = "CountryData";
private readonly ICrmService _crmService;
public ReferenceDataProvider(ICrmService crmService)
{
_crmService = crmService;
}
public IEnumerable<CountryLookupDto> GetCountries()
{
//if in cache then get cached version
if (CacheManager.GetInstance.OCache.Contains(REF_DATA_COUNTRIES))
return CacheManager.GetInstance.GetTypedItem<IEnumerable<CountryLookupDto>>(REF_DATA_COUNTRIES);
try
{
IEnumerable<CountryLookupDto> countriesDto = _crmService.LookupCountries("*");
bool addedToCache = CacheManager.GetInstance.AddItemWithExpiration(REF_DATA_COUNTRIES, countriesDto,
12);
if (!addedToCache) throw new Exception("Cannot add ref data to cache");
}
catch (Exception ex)
{
LoggingManager.GetInstance.Log("Error", ex, LoggingManager.LogLevel.Error);
throw;
}
return CacheManager.GetInstance.GetTypedItem<IEnumerable<CountryLookupDto>>(REF_DATA_COUNTRIES);
}
}
My question here is I had service.Close() before. Now I can't use it. Is that safe ?
If CrmServiceClient is your WCF service so you should have an interface ICrmServiceClient.
Therefore you should not create new instance of CrmServiceClient in your code. The only thing your need is a dependency on ICrmServiceClient (e.g. via constructor)
public class RefDataProvider : IRefDataProvider
{
private readonly ICrmServiceClient crmServiceClient;
public RefDataProvider(ICrmServiceClient crmServiceClient)
{
this.crmServiceClient = crmServiceClient;
}
public IEnumerable<CountryLookupDto> GetCountries()
{
/* your code */
}
}
In this case it is possible to inject mock ok ICrmServiceClient easily.
[TestFixture]
public class TestRefDataProvider
{
private Mock<ICrmServiceClient> crmServiceClientMock;
private IReferenceDataProvider _referenceDataProvider;
[SetUp]
public void SetUp()
{
crmServiceClientMock = new Mock<ICrmServiceClient>();
crmServiceClientMock
.Setuo(/* your code */)
.Returns(/* your code */);
_referenceDataProvider = new ReferenceDataProvider(
crmServiceClientMock.Object
);
}
}
MOQ framework is used in order to mock dependencies.
I have a situation where I have multiple producers and multiple consumers. The producers enters a job into a queue. I chose the BlockingCollection and it works great since I need the consumers to wait for a job to be found. However, if I use the GetConsumingEnumerable() feature the order of the items in the collection change... this is not what I need.
It even says in MSDN http://msdn.microsoft.com/en-us/library/dd287186.aspx
that it does not preserve the order of the items.
Does anyone know an alternative for this situation?
I see that the Take method is available but does it also provide a 'wait' condition for the consumer threads?
It says http://msdn.microsoft.com/en-us/library/dd287085.aspx
'A call to Take may block until an item is available to be removed.' Is it better to use TryTake? I really need the thread to wait and keep checking for a job.
Take blocks the thread till something comes available.
TryTake as the name implies tries to do so but returns a bool if it fails or succeeds.
Allowing for more flex using it:
while(goingOn){
if( q.TryTake(out var){
Process(var)
}
else{
DoSomething_Usefull_OrNotUseFull_OrEvenSleep();
}
}
instead of
while(goingOn){
if( var x = q.Take(){
//w'll wait till this ever will happen and then we:
Process(var)
}
}
My votes are for TryTake :-)
EXAMPLE:
public class ProducerConsumer<T> {
public struct Message {
public T Data;
}
private readonly ThreadRunner _producer;
private readonly ThreadRunner _consumer;
public ProducerConsumer(Func<T> produce, Action<T> consume) {
var q = new BlockingCollection<Message>();
_producer = new Producer(produce,q);
_consumer = new Consumer(consume,q);
}
public void Start() {
_producer.Run();
_consumer.Run();
}
public void Stop() {
_producer.Stop();
_consumer.Stop();
}
private class Producer : ThreadRunner {
public Producer(Func<T> produce, BlockingCollection<Message> q) : base(q) {
_produce = produce;
}
private readonly Func<T> _produce;
public override void Worker() {
try {
while (KeepRunning) {
var item = _produce();
MessageQ.TryAdd(new Message{Data = item});
}
}
catch (ThreadInterruptedException) {
WasInterrupted = true;
}
}
}
public abstract class ThreadRunner {
protected readonly BlockingCollection<Message> MessageQ;
protected ThreadRunner(BlockingCollection<Message> q) {
MessageQ = q;
}
protected Thread Runner;
protected bool KeepRunning = true;
public bool WasInterrupted;
public abstract void Worker();
public void Run() {
Runner = new Thread(Worker);
Runner.Start();
}
public void Stop() {
KeepRunning = false;
Runner.Interrupt();
Runner.Join();
}
}
class Consumer : ThreadRunner {
private readonly Action<T> _consume;
public Consumer(Action<T> consume,BlockingCollection<Message> q) : base(q) {
_consume = consume;
}
public override void Worker() {
try {
while (KeepRunning) {
Message message;
if (MessageQ.TryTake(out message, TimeSpan.FromMilliseconds(100))) {
_consume(message.Data);
}
else {
//There's nothing in the Q so I have some spare time...
//Excellent moment to update my statisics or update some history to logfiles
//for now we sleep:
Thread.Sleep(TimeSpan.FromMilliseconds(100));
}
}
}
catch (ThreadInterruptedException) {
WasInterrupted = true;
}
}
}
}
}
USAGE:
[Fact]
public void ConsumerShouldConsume() {
var produced = 0;
var consumed = 0;
Func<int> produce = () => {
Thread.Sleep(TimeSpan.FromMilliseconds(100));
produced++;
return new Random(2).Next(1000);
};
Action<int> consume = c => { consumed++; };
var t = new ProducerConsumer<int>(produce, consume);
t.Start();
Thread.Sleep(TimeSpan.FromSeconds(5));
t.Stop();
Assert.InRange(produced,40,60);
Assert.InRange(consumed, 40, 60);
}