Consumer Producer- Producer thread never executes assigned function












0














I have .NET Core Web API solution. In each call, I need to perform some database operations.
The issue is at a time multiple db connections get opened & close. So to avoid it, I want to implement Queue of objects to be sent to database and then want a separate thread to perform db operation.

I've tried some code as below. But here, Consumer thread never executes assigned function. There is no separate thread for Producer, I am simply feeding queue with object.

What modifications I should do? Need some guidance as I'm new to Threading stuff.



  public static class BlockingQueue
{
public static Queue<WebServiceLogModel> queue;
static BlockingQueue()
{
queue = new Queue<WebServiceLogModel>();

}

public static object Dequeue()
{
lock (queue)
{
while (queue.Count == 0)
{
Monitor.Wait(queue);
}
return queue.Dequeue();
}
}
public static void Enqueue(WebServiceLogModel webServiceLog)
{
lock (queue)
{
queue.Enqueue(webServiceLog);
Monitor.Pulse(queue);
}
}

public static void ConsumerThread(IConfiguration configuration)
{
WebServiceLogModel webServiceLog = (WebServiceLogModel)Dequeue();
webServiceLog.SaveWebServiceLog(configuration);
}

public static void ProducerThread(WebServiceLogModel webServiceLog)
{
Enqueue(webServiceLog);
Thread.Sleep(100);
}
}


I've created and started thread in StartUp.cs:



    public Startup(IConfiguration configuration)
{
Thread t = new Thread(() => BlockingQueue.ConsumerThread(configuration));
t.Start();
}


In Controller, I've written code to feed the queue:



    [HttpGet]
[Route("abc")]
public IActionResult GetData()
{
BlockingQueue.ProducerThread(logModel);
return StatusCode(HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound, ApplicationConstants.Message.NoBatchHistoryInfo);
}









share|improve this question






















  • "The issue is at a time multiple db connections get opened & close. So to avoid it" why do you want to do this, do you have a concurrency problem?
    – TheGeneral
    Nov 21 at 6:56












  • yes. concurrency issue I am facing. Any suggestions for that?
    – Priya
    Nov 21 at 6:57










  • I will check TPL too then, if it is helpful then.
    – Priya
    Nov 21 at 7:03










  • Two suggestions, firstly don't make the object you are using as a lock public. It's hard enough to make sure that you don't deadlock something without allowing other objects to join the party. Secondly, take a look at BlockingCollection which implements a producer consumer pattern for you.
    – Adam G
    Nov 21 at 7:23










  • Blocking collection I've heard about. I will check if its helpful in my case. Thanks.
    – Priya
    Nov 21 at 7:45
















0














I have .NET Core Web API solution. In each call, I need to perform some database operations.
The issue is at a time multiple db connections get opened & close. So to avoid it, I want to implement Queue of objects to be sent to database and then want a separate thread to perform db operation.

I've tried some code as below. But here, Consumer thread never executes assigned function. There is no separate thread for Producer, I am simply feeding queue with object.

What modifications I should do? Need some guidance as I'm new to Threading stuff.



  public static class BlockingQueue
{
public static Queue<WebServiceLogModel> queue;
static BlockingQueue()
{
queue = new Queue<WebServiceLogModel>();

}

public static object Dequeue()
{
lock (queue)
{
while (queue.Count == 0)
{
Monitor.Wait(queue);
}
return queue.Dequeue();
}
}
public static void Enqueue(WebServiceLogModel webServiceLog)
{
lock (queue)
{
queue.Enqueue(webServiceLog);
Monitor.Pulse(queue);
}
}

public static void ConsumerThread(IConfiguration configuration)
{
WebServiceLogModel webServiceLog = (WebServiceLogModel)Dequeue();
webServiceLog.SaveWebServiceLog(configuration);
}

public static void ProducerThread(WebServiceLogModel webServiceLog)
{
Enqueue(webServiceLog);
Thread.Sleep(100);
}
}


I've created and started thread in StartUp.cs:



    public Startup(IConfiguration configuration)
{
Thread t = new Thread(() => BlockingQueue.ConsumerThread(configuration));
t.Start();
}


In Controller, I've written code to feed the queue:



    [HttpGet]
[Route("abc")]
public IActionResult GetData()
{
BlockingQueue.ProducerThread(logModel);
return StatusCode(HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound, ApplicationConstants.Message.NoBatchHistoryInfo);
}









share|improve this question






















  • "The issue is at a time multiple db connections get opened & close. So to avoid it" why do you want to do this, do you have a concurrency problem?
    – TheGeneral
    Nov 21 at 6:56












  • yes. concurrency issue I am facing. Any suggestions for that?
    – Priya
    Nov 21 at 6:57










  • I will check TPL too then, if it is helpful then.
    – Priya
    Nov 21 at 7:03










  • Two suggestions, firstly don't make the object you are using as a lock public. It's hard enough to make sure that you don't deadlock something without allowing other objects to join the party. Secondly, take a look at BlockingCollection which implements a producer consumer pattern for you.
    – Adam G
    Nov 21 at 7:23










  • Blocking collection I've heard about. I will check if its helpful in my case. Thanks.
    – Priya
    Nov 21 at 7:45














0












0








0







I have .NET Core Web API solution. In each call, I need to perform some database operations.
The issue is at a time multiple db connections get opened & close. So to avoid it, I want to implement Queue of objects to be sent to database and then want a separate thread to perform db operation.

I've tried some code as below. But here, Consumer thread never executes assigned function. There is no separate thread for Producer, I am simply feeding queue with object.

What modifications I should do? Need some guidance as I'm new to Threading stuff.



  public static class BlockingQueue
{
public static Queue<WebServiceLogModel> queue;
static BlockingQueue()
{
queue = new Queue<WebServiceLogModel>();

}

public static object Dequeue()
{
lock (queue)
{
while (queue.Count == 0)
{
Monitor.Wait(queue);
}
return queue.Dequeue();
}
}
public static void Enqueue(WebServiceLogModel webServiceLog)
{
lock (queue)
{
queue.Enqueue(webServiceLog);
Monitor.Pulse(queue);
}
}

public static void ConsumerThread(IConfiguration configuration)
{
WebServiceLogModel webServiceLog = (WebServiceLogModel)Dequeue();
webServiceLog.SaveWebServiceLog(configuration);
}

public static void ProducerThread(WebServiceLogModel webServiceLog)
{
Enqueue(webServiceLog);
Thread.Sleep(100);
}
}


I've created and started thread in StartUp.cs:



    public Startup(IConfiguration configuration)
{
Thread t = new Thread(() => BlockingQueue.ConsumerThread(configuration));
t.Start();
}


In Controller, I've written code to feed the queue:



    [HttpGet]
[Route("abc")]
public IActionResult GetData()
{
BlockingQueue.ProducerThread(logModel);
return StatusCode(HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound, ApplicationConstants.Message.NoBatchHistoryInfo);
}









share|improve this question













I have .NET Core Web API solution. In each call, I need to perform some database operations.
The issue is at a time multiple db connections get opened & close. So to avoid it, I want to implement Queue of objects to be sent to database and then want a separate thread to perform db operation.

I've tried some code as below. But here, Consumer thread never executes assigned function. There is no separate thread for Producer, I am simply feeding queue with object.

What modifications I should do? Need some guidance as I'm new to Threading stuff.



  public static class BlockingQueue
{
public static Queue<WebServiceLogModel> queue;
static BlockingQueue()
{
queue = new Queue<WebServiceLogModel>();

}

public static object Dequeue()
{
lock (queue)
{
while (queue.Count == 0)
{
Monitor.Wait(queue);
}
return queue.Dequeue();
}
}
public static void Enqueue(WebServiceLogModel webServiceLog)
{
lock (queue)
{
queue.Enqueue(webServiceLog);
Monitor.Pulse(queue);
}
}

public static void ConsumerThread(IConfiguration configuration)
{
WebServiceLogModel webServiceLog = (WebServiceLogModel)Dequeue();
webServiceLog.SaveWebServiceLog(configuration);
}

public static void ProducerThread(WebServiceLogModel webServiceLog)
{
Enqueue(webServiceLog);
Thread.Sleep(100);
}
}


I've created and started thread in StartUp.cs:



    public Startup(IConfiguration configuration)
{
Thread t = new Thread(() => BlockingQueue.ConsumerThread(configuration));
t.Start();
}


In Controller, I've written code to feed the queue:



    [HttpGet]
[Route("abc")]
public IActionResult GetData()
{
BlockingQueue.ProducerThread(logModel);
return StatusCode(HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound, ApplicationConstants.Message.NoBatchHistoryInfo);
}






c# multithreading .net-core queue thread-synchronization






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 at 6:54









Priya

61151231




61151231












  • "The issue is at a time multiple db connections get opened & close. So to avoid it" why do you want to do this, do you have a concurrency problem?
    – TheGeneral
    Nov 21 at 6:56












  • yes. concurrency issue I am facing. Any suggestions for that?
    – Priya
    Nov 21 at 6:57










  • I will check TPL too then, if it is helpful then.
    – Priya
    Nov 21 at 7:03










  • Two suggestions, firstly don't make the object you are using as a lock public. It's hard enough to make sure that you don't deadlock something without allowing other objects to join the party. Secondly, take a look at BlockingCollection which implements a producer consumer pattern for you.
    – Adam G
    Nov 21 at 7:23










  • Blocking collection I've heard about. I will check if its helpful in my case. Thanks.
    – Priya
    Nov 21 at 7:45


















  • "The issue is at a time multiple db connections get opened & close. So to avoid it" why do you want to do this, do you have a concurrency problem?
    – TheGeneral
    Nov 21 at 6:56












  • yes. concurrency issue I am facing. Any suggestions for that?
    – Priya
    Nov 21 at 6:57










  • I will check TPL too then, if it is helpful then.
    – Priya
    Nov 21 at 7:03










  • Two suggestions, firstly don't make the object you are using as a lock public. It's hard enough to make sure that you don't deadlock something without allowing other objects to join the party. Secondly, take a look at BlockingCollection which implements a producer consumer pattern for you.
    – Adam G
    Nov 21 at 7:23










  • Blocking collection I've heard about. I will check if its helpful in my case. Thanks.
    – Priya
    Nov 21 at 7:45
















"The issue is at a time multiple db connections get opened & close. So to avoid it" why do you want to do this, do you have a concurrency problem?
– TheGeneral
Nov 21 at 6:56






"The issue is at a time multiple db connections get opened & close. So to avoid it" why do you want to do this, do you have a concurrency problem?
– TheGeneral
Nov 21 at 6:56














yes. concurrency issue I am facing. Any suggestions for that?
– Priya
Nov 21 at 6:57




yes. concurrency issue I am facing. Any suggestions for that?
– Priya
Nov 21 at 6:57












I will check TPL too then, if it is helpful then.
– Priya
Nov 21 at 7:03




I will check TPL too then, if it is helpful then.
– Priya
Nov 21 at 7:03












Two suggestions, firstly don't make the object you are using as a lock public. It's hard enough to make sure that you don't deadlock something without allowing other objects to join the party. Secondly, take a look at BlockingCollection which implements a producer consumer pattern for you.
– Adam G
Nov 21 at 7:23




Two suggestions, firstly don't make the object you are using as a lock public. It's hard enough to make sure that you don't deadlock something without allowing other objects to join the party. Secondly, take a look at BlockingCollection which implements a producer consumer pattern for you.
– Adam G
Nov 21 at 7:23












Blocking collection I've heard about. I will check if its helpful in my case. Thanks.
– Priya
Nov 21 at 7:45




Blocking collection I've heard about. I will check if its helpful in my case. Thanks.
– Priya
Nov 21 at 7:45












2 Answers
2






active

oldest

votes


















1














First of all, try to avoid static classes and methods. Use pattern singleton in that case (and if you really need this).
Second, try to avoid lock, Monitor - those concurrency primitives significantly lower your performance.
In such situation, you can use BlockingCollection<> as 'Adam G' mentioned above, or you can develop your own solution.



public class Service : IDisposable
{
private readonly BlockingCollection<WebServiceLogModel> _packets =
new BlockingCollection<WebServiceLogModel>();
private Task _task;
private volatile bool _active;
private static readonly TimeSpan WaitTimeout = TimeSpan.FromSeconds(1);

public Service()
{
_active = true;
_task = ExecTaskInternal();
}

public void Enqueue(WebServiceLogModel model)
{
_packets.Add(model);
}

public void Dispose()
{
_active = false;
}

private async Task ExecTaskInternal()
{
while (_active)
{
if (_packets.TryTake(out WebServiceLogModel model))
{
// TODO: whatever you need
}
else
{
await Task.Delay(WaitTimeout);
}
}
}
}

public class MyController : Controller
{
[HttpGet]
[Route("abc")]
public IActionResult GetData([FromServices] Service service)
{
// receive model form somewhere
WebServiceLogModel model = FetchModel();
// enqueue model
service.Enqueue(model);
// TODO: return what you need
}
}


And in Startup:



public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Service>();
// TODO: other init staffs
}
}


You even can add Start/Stop methods to the service instead of implementing IDisposable and start your service in the startup class in the method Configure(IApplicationBuilder app).






share|improve this answer





















  • Hi Igor. Thanks for providing solution. I've implemented with few modification as per my requirements. I have not worked with threads before. So was stuck. Btw, will this work flawlessly if multiple endpoints will try to add WebServiceLog concurrently? Thanks again for help! :)
    – Priya
    Nov 21 at 13:02






  • 1




    According to the documentation: link this class was designed for concurrent access.
    – Igor Goyda
    Nov 21 at 13:16



















0














I think your consumer thread is executed just once if there is something in the queue and then immediately returns. If you want to have a thread doing work in background, which is started just once, it should never return and should catch all exceptions. Your thread from BlockingQueue.ConsumerThread is invoked once in Stratup and returns.



Also please be aware that doing such solution is not safe. ASP.NET doesn't guarantee background threads to be running if there are no requests coming in. Your application pool can recycle (and by default it recycles after 20 minutes of inactivity or every 27 hours), so there is a chance that your background code won't be executed for some queue items.



Also, while it doesn't solve all issues, I would suggest using https://www.hangfire.io/ to do background tasks in ASP.NET server. It has persistence layer, can retry jobs and has simple API's. In your request handler you can push new jobs to Hangfire and then have just 1 job processor thread.






share|improve this answer





















  • What could be the efficient solution for such issues? I am facing concurrency issue. So want to store object in queue and then want a separate thread to perform db stuff.
    – Priya
    Nov 21 at 7:06










  • Ideal and most reliable solution would be to have separate queue (RabbitMQ/ServiceBus etc) and separate service that is not running in ASP.Net (another machine / windows service etc) that will process that queue. Reason: survive app domain restarts, because if you have big queue of tasks in memory and app domain restarts, you lose it all.
    – dlxeon
    Nov 21 at 7:08












  • Depending on your situation, good enough solution can be to use HangFire. It will handle for you persistence, thread management, locks etc. You can just push items to it and then it will call your job handler.
    – dlxeon
    Nov 21 at 7:09










  • Unfortunately, I won't be able to use any third party solutions n required to solve this issue with help of pure .net concepts. :|
    – Priya
    Nov 21 at 7:14










  • Actually, I'm a little bit unsure if concurrent database operations is root cause of issue, because databases are designed to handle lots of queries. But if you do believe that's the case, maybe you can tweak database connection pool settings to allow just 1 connection for whole application docs.microsoft.com/en-us/dotnet/framework/data/adonet/… , but then you should add retries and error handling implementation for every database access, because now it may fail due to timeout/lack of connection available.
    – dlxeon
    Nov 21 at 7:19











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53406692%2fconsumer-producer-producer-thread-never-executes-assigned-function%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














First of all, try to avoid static classes and methods. Use pattern singleton in that case (and if you really need this).
Second, try to avoid lock, Monitor - those concurrency primitives significantly lower your performance.
In such situation, you can use BlockingCollection<> as 'Adam G' mentioned above, or you can develop your own solution.



public class Service : IDisposable
{
private readonly BlockingCollection<WebServiceLogModel> _packets =
new BlockingCollection<WebServiceLogModel>();
private Task _task;
private volatile bool _active;
private static readonly TimeSpan WaitTimeout = TimeSpan.FromSeconds(1);

public Service()
{
_active = true;
_task = ExecTaskInternal();
}

public void Enqueue(WebServiceLogModel model)
{
_packets.Add(model);
}

public void Dispose()
{
_active = false;
}

private async Task ExecTaskInternal()
{
while (_active)
{
if (_packets.TryTake(out WebServiceLogModel model))
{
// TODO: whatever you need
}
else
{
await Task.Delay(WaitTimeout);
}
}
}
}

public class MyController : Controller
{
[HttpGet]
[Route("abc")]
public IActionResult GetData([FromServices] Service service)
{
// receive model form somewhere
WebServiceLogModel model = FetchModel();
// enqueue model
service.Enqueue(model);
// TODO: return what you need
}
}


And in Startup:



public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Service>();
// TODO: other init staffs
}
}


You even can add Start/Stop methods to the service instead of implementing IDisposable and start your service in the startup class in the method Configure(IApplicationBuilder app).






share|improve this answer





















  • Hi Igor. Thanks for providing solution. I've implemented with few modification as per my requirements. I have not worked with threads before. So was stuck. Btw, will this work flawlessly if multiple endpoints will try to add WebServiceLog concurrently? Thanks again for help! :)
    – Priya
    Nov 21 at 13:02






  • 1




    According to the documentation: link this class was designed for concurrent access.
    – Igor Goyda
    Nov 21 at 13:16
















1














First of all, try to avoid static classes and methods. Use pattern singleton in that case (and if you really need this).
Second, try to avoid lock, Monitor - those concurrency primitives significantly lower your performance.
In such situation, you can use BlockingCollection<> as 'Adam G' mentioned above, or you can develop your own solution.



public class Service : IDisposable
{
private readonly BlockingCollection<WebServiceLogModel> _packets =
new BlockingCollection<WebServiceLogModel>();
private Task _task;
private volatile bool _active;
private static readonly TimeSpan WaitTimeout = TimeSpan.FromSeconds(1);

public Service()
{
_active = true;
_task = ExecTaskInternal();
}

public void Enqueue(WebServiceLogModel model)
{
_packets.Add(model);
}

public void Dispose()
{
_active = false;
}

private async Task ExecTaskInternal()
{
while (_active)
{
if (_packets.TryTake(out WebServiceLogModel model))
{
// TODO: whatever you need
}
else
{
await Task.Delay(WaitTimeout);
}
}
}
}

public class MyController : Controller
{
[HttpGet]
[Route("abc")]
public IActionResult GetData([FromServices] Service service)
{
// receive model form somewhere
WebServiceLogModel model = FetchModel();
// enqueue model
service.Enqueue(model);
// TODO: return what you need
}
}


And in Startup:



public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Service>();
// TODO: other init staffs
}
}


You even can add Start/Stop methods to the service instead of implementing IDisposable and start your service in the startup class in the method Configure(IApplicationBuilder app).






share|improve this answer





















  • Hi Igor. Thanks for providing solution. I've implemented with few modification as per my requirements. I have not worked with threads before. So was stuck. Btw, will this work flawlessly if multiple endpoints will try to add WebServiceLog concurrently? Thanks again for help! :)
    – Priya
    Nov 21 at 13:02






  • 1




    According to the documentation: link this class was designed for concurrent access.
    – Igor Goyda
    Nov 21 at 13:16














1












1








1






First of all, try to avoid static classes and methods. Use pattern singleton in that case (and if you really need this).
Second, try to avoid lock, Monitor - those concurrency primitives significantly lower your performance.
In such situation, you can use BlockingCollection<> as 'Adam G' mentioned above, or you can develop your own solution.



public class Service : IDisposable
{
private readonly BlockingCollection<WebServiceLogModel> _packets =
new BlockingCollection<WebServiceLogModel>();
private Task _task;
private volatile bool _active;
private static readonly TimeSpan WaitTimeout = TimeSpan.FromSeconds(1);

public Service()
{
_active = true;
_task = ExecTaskInternal();
}

public void Enqueue(WebServiceLogModel model)
{
_packets.Add(model);
}

public void Dispose()
{
_active = false;
}

private async Task ExecTaskInternal()
{
while (_active)
{
if (_packets.TryTake(out WebServiceLogModel model))
{
// TODO: whatever you need
}
else
{
await Task.Delay(WaitTimeout);
}
}
}
}

public class MyController : Controller
{
[HttpGet]
[Route("abc")]
public IActionResult GetData([FromServices] Service service)
{
// receive model form somewhere
WebServiceLogModel model = FetchModel();
// enqueue model
service.Enqueue(model);
// TODO: return what you need
}
}


And in Startup:



public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Service>();
// TODO: other init staffs
}
}


You even can add Start/Stop methods to the service instead of implementing IDisposable and start your service in the startup class in the method Configure(IApplicationBuilder app).






share|improve this answer












First of all, try to avoid static classes and methods. Use pattern singleton in that case (and if you really need this).
Second, try to avoid lock, Monitor - those concurrency primitives significantly lower your performance.
In such situation, you can use BlockingCollection<> as 'Adam G' mentioned above, or you can develop your own solution.



public class Service : IDisposable
{
private readonly BlockingCollection<WebServiceLogModel> _packets =
new BlockingCollection<WebServiceLogModel>();
private Task _task;
private volatile bool _active;
private static readonly TimeSpan WaitTimeout = TimeSpan.FromSeconds(1);

public Service()
{
_active = true;
_task = ExecTaskInternal();
}

public void Enqueue(WebServiceLogModel model)
{
_packets.Add(model);
}

public void Dispose()
{
_active = false;
}

private async Task ExecTaskInternal()
{
while (_active)
{
if (_packets.TryTake(out WebServiceLogModel model))
{
// TODO: whatever you need
}
else
{
await Task.Delay(WaitTimeout);
}
}
}
}

public class MyController : Controller
{
[HttpGet]
[Route("abc")]
public IActionResult GetData([FromServices] Service service)
{
// receive model form somewhere
WebServiceLogModel model = FetchModel();
// enqueue model
service.Enqueue(model);
// TODO: return what you need
}
}


And in Startup:



public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Service>();
// TODO: other init staffs
}
}


You even can add Start/Stop methods to the service instead of implementing IDisposable and start your service in the startup class in the method Configure(IApplicationBuilder app).







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 at 9:38









Igor Goyda

2313




2313












  • Hi Igor. Thanks for providing solution. I've implemented with few modification as per my requirements. I have not worked with threads before. So was stuck. Btw, will this work flawlessly if multiple endpoints will try to add WebServiceLog concurrently? Thanks again for help! :)
    – Priya
    Nov 21 at 13:02






  • 1




    According to the documentation: link this class was designed for concurrent access.
    – Igor Goyda
    Nov 21 at 13:16


















  • Hi Igor. Thanks for providing solution. I've implemented with few modification as per my requirements. I have not worked with threads before. So was stuck. Btw, will this work flawlessly if multiple endpoints will try to add WebServiceLog concurrently? Thanks again for help! :)
    – Priya
    Nov 21 at 13:02






  • 1




    According to the documentation: link this class was designed for concurrent access.
    – Igor Goyda
    Nov 21 at 13:16
















Hi Igor. Thanks for providing solution. I've implemented with few modification as per my requirements. I have not worked with threads before. So was stuck. Btw, will this work flawlessly if multiple endpoints will try to add WebServiceLog concurrently? Thanks again for help! :)
– Priya
Nov 21 at 13:02




Hi Igor. Thanks for providing solution. I've implemented with few modification as per my requirements. I have not worked with threads before. So was stuck. Btw, will this work flawlessly if multiple endpoints will try to add WebServiceLog concurrently? Thanks again for help! :)
– Priya
Nov 21 at 13:02




1




1




According to the documentation: link this class was designed for concurrent access.
– Igor Goyda
Nov 21 at 13:16




According to the documentation: link this class was designed for concurrent access.
– Igor Goyda
Nov 21 at 13:16













0














I think your consumer thread is executed just once if there is something in the queue and then immediately returns. If you want to have a thread doing work in background, which is started just once, it should never return and should catch all exceptions. Your thread from BlockingQueue.ConsumerThread is invoked once in Stratup and returns.



Also please be aware that doing such solution is not safe. ASP.NET doesn't guarantee background threads to be running if there are no requests coming in. Your application pool can recycle (and by default it recycles after 20 minutes of inactivity or every 27 hours), so there is a chance that your background code won't be executed for some queue items.



Also, while it doesn't solve all issues, I would suggest using https://www.hangfire.io/ to do background tasks in ASP.NET server. It has persistence layer, can retry jobs and has simple API's. In your request handler you can push new jobs to Hangfire and then have just 1 job processor thread.






share|improve this answer





















  • What could be the efficient solution for such issues? I am facing concurrency issue. So want to store object in queue and then want a separate thread to perform db stuff.
    – Priya
    Nov 21 at 7:06










  • Ideal and most reliable solution would be to have separate queue (RabbitMQ/ServiceBus etc) and separate service that is not running in ASP.Net (another machine / windows service etc) that will process that queue. Reason: survive app domain restarts, because if you have big queue of tasks in memory and app domain restarts, you lose it all.
    – dlxeon
    Nov 21 at 7:08












  • Depending on your situation, good enough solution can be to use HangFire. It will handle for you persistence, thread management, locks etc. You can just push items to it and then it will call your job handler.
    – dlxeon
    Nov 21 at 7:09










  • Unfortunately, I won't be able to use any third party solutions n required to solve this issue with help of pure .net concepts. :|
    – Priya
    Nov 21 at 7:14










  • Actually, I'm a little bit unsure if concurrent database operations is root cause of issue, because databases are designed to handle lots of queries. But if you do believe that's the case, maybe you can tweak database connection pool settings to allow just 1 connection for whole application docs.microsoft.com/en-us/dotnet/framework/data/adonet/… , but then you should add retries and error handling implementation for every database access, because now it may fail due to timeout/lack of connection available.
    – dlxeon
    Nov 21 at 7:19
















0














I think your consumer thread is executed just once if there is something in the queue and then immediately returns. If you want to have a thread doing work in background, which is started just once, it should never return and should catch all exceptions. Your thread from BlockingQueue.ConsumerThread is invoked once in Stratup and returns.



Also please be aware that doing such solution is not safe. ASP.NET doesn't guarantee background threads to be running if there are no requests coming in. Your application pool can recycle (and by default it recycles after 20 minutes of inactivity or every 27 hours), so there is a chance that your background code won't be executed for some queue items.



Also, while it doesn't solve all issues, I would suggest using https://www.hangfire.io/ to do background tasks in ASP.NET server. It has persistence layer, can retry jobs and has simple API's. In your request handler you can push new jobs to Hangfire and then have just 1 job processor thread.






share|improve this answer





















  • What could be the efficient solution for such issues? I am facing concurrency issue. So want to store object in queue and then want a separate thread to perform db stuff.
    – Priya
    Nov 21 at 7:06










  • Ideal and most reliable solution would be to have separate queue (RabbitMQ/ServiceBus etc) and separate service that is not running in ASP.Net (another machine / windows service etc) that will process that queue. Reason: survive app domain restarts, because if you have big queue of tasks in memory and app domain restarts, you lose it all.
    – dlxeon
    Nov 21 at 7:08












  • Depending on your situation, good enough solution can be to use HangFire. It will handle for you persistence, thread management, locks etc. You can just push items to it and then it will call your job handler.
    – dlxeon
    Nov 21 at 7:09










  • Unfortunately, I won't be able to use any third party solutions n required to solve this issue with help of pure .net concepts. :|
    – Priya
    Nov 21 at 7:14










  • Actually, I'm a little bit unsure if concurrent database operations is root cause of issue, because databases are designed to handle lots of queries. But if you do believe that's the case, maybe you can tweak database connection pool settings to allow just 1 connection for whole application docs.microsoft.com/en-us/dotnet/framework/data/adonet/… , but then you should add retries and error handling implementation for every database access, because now it may fail due to timeout/lack of connection available.
    – dlxeon
    Nov 21 at 7:19














0












0








0






I think your consumer thread is executed just once if there is something in the queue and then immediately returns. If you want to have a thread doing work in background, which is started just once, it should never return and should catch all exceptions. Your thread from BlockingQueue.ConsumerThread is invoked once in Stratup and returns.



Also please be aware that doing such solution is not safe. ASP.NET doesn't guarantee background threads to be running if there are no requests coming in. Your application pool can recycle (and by default it recycles after 20 minutes of inactivity or every 27 hours), so there is a chance that your background code won't be executed for some queue items.



Also, while it doesn't solve all issues, I would suggest using https://www.hangfire.io/ to do background tasks in ASP.NET server. It has persistence layer, can retry jobs and has simple API's. In your request handler you can push new jobs to Hangfire and then have just 1 job processor thread.






share|improve this answer












I think your consumer thread is executed just once if there is something in the queue and then immediately returns. If you want to have a thread doing work in background, which is started just once, it should never return and should catch all exceptions. Your thread from BlockingQueue.ConsumerThread is invoked once in Stratup and returns.



Also please be aware that doing such solution is not safe. ASP.NET doesn't guarantee background threads to be running if there are no requests coming in. Your application pool can recycle (and by default it recycles after 20 minutes of inactivity or every 27 hours), so there is a chance that your background code won't be executed for some queue items.



Also, while it doesn't solve all issues, I would suggest using https://www.hangfire.io/ to do background tasks in ASP.NET server. It has persistence layer, can retry jobs and has simple API's. In your request handler you can push new jobs to Hangfire and then have just 1 job processor thread.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 at 7:00









dlxeon

1,51289




1,51289












  • What could be the efficient solution for such issues? I am facing concurrency issue. So want to store object in queue and then want a separate thread to perform db stuff.
    – Priya
    Nov 21 at 7:06










  • Ideal and most reliable solution would be to have separate queue (RabbitMQ/ServiceBus etc) and separate service that is not running in ASP.Net (another machine / windows service etc) that will process that queue. Reason: survive app domain restarts, because if you have big queue of tasks in memory and app domain restarts, you lose it all.
    – dlxeon
    Nov 21 at 7:08












  • Depending on your situation, good enough solution can be to use HangFire. It will handle for you persistence, thread management, locks etc. You can just push items to it and then it will call your job handler.
    – dlxeon
    Nov 21 at 7:09










  • Unfortunately, I won't be able to use any third party solutions n required to solve this issue with help of pure .net concepts. :|
    – Priya
    Nov 21 at 7:14










  • Actually, I'm a little bit unsure if concurrent database operations is root cause of issue, because databases are designed to handle lots of queries. But if you do believe that's the case, maybe you can tweak database connection pool settings to allow just 1 connection for whole application docs.microsoft.com/en-us/dotnet/framework/data/adonet/… , but then you should add retries and error handling implementation for every database access, because now it may fail due to timeout/lack of connection available.
    – dlxeon
    Nov 21 at 7:19


















  • What could be the efficient solution for such issues? I am facing concurrency issue. So want to store object in queue and then want a separate thread to perform db stuff.
    – Priya
    Nov 21 at 7:06










  • Ideal and most reliable solution would be to have separate queue (RabbitMQ/ServiceBus etc) and separate service that is not running in ASP.Net (another machine / windows service etc) that will process that queue. Reason: survive app domain restarts, because if you have big queue of tasks in memory and app domain restarts, you lose it all.
    – dlxeon
    Nov 21 at 7:08












  • Depending on your situation, good enough solution can be to use HangFire. It will handle for you persistence, thread management, locks etc. You can just push items to it and then it will call your job handler.
    – dlxeon
    Nov 21 at 7:09










  • Unfortunately, I won't be able to use any third party solutions n required to solve this issue with help of pure .net concepts. :|
    – Priya
    Nov 21 at 7:14










  • Actually, I'm a little bit unsure if concurrent database operations is root cause of issue, because databases are designed to handle lots of queries. But if you do believe that's the case, maybe you can tweak database connection pool settings to allow just 1 connection for whole application docs.microsoft.com/en-us/dotnet/framework/data/adonet/… , but then you should add retries and error handling implementation for every database access, because now it may fail due to timeout/lack of connection available.
    – dlxeon
    Nov 21 at 7:19
















What could be the efficient solution for such issues? I am facing concurrency issue. So want to store object in queue and then want a separate thread to perform db stuff.
– Priya
Nov 21 at 7:06




What could be the efficient solution for such issues? I am facing concurrency issue. So want to store object in queue and then want a separate thread to perform db stuff.
– Priya
Nov 21 at 7:06












Ideal and most reliable solution would be to have separate queue (RabbitMQ/ServiceBus etc) and separate service that is not running in ASP.Net (another machine / windows service etc) that will process that queue. Reason: survive app domain restarts, because if you have big queue of tasks in memory and app domain restarts, you lose it all.
– dlxeon
Nov 21 at 7:08






Ideal and most reliable solution would be to have separate queue (RabbitMQ/ServiceBus etc) and separate service that is not running in ASP.Net (another machine / windows service etc) that will process that queue. Reason: survive app domain restarts, because if you have big queue of tasks in memory and app domain restarts, you lose it all.
– dlxeon
Nov 21 at 7:08














Depending on your situation, good enough solution can be to use HangFire. It will handle for you persistence, thread management, locks etc. You can just push items to it and then it will call your job handler.
– dlxeon
Nov 21 at 7:09




Depending on your situation, good enough solution can be to use HangFire. It will handle for you persistence, thread management, locks etc. You can just push items to it and then it will call your job handler.
– dlxeon
Nov 21 at 7:09












Unfortunately, I won't be able to use any third party solutions n required to solve this issue with help of pure .net concepts. :|
– Priya
Nov 21 at 7:14




Unfortunately, I won't be able to use any third party solutions n required to solve this issue with help of pure .net concepts. :|
– Priya
Nov 21 at 7:14












Actually, I'm a little bit unsure if concurrent database operations is root cause of issue, because databases are designed to handle lots of queries. But if you do believe that's the case, maybe you can tweak database connection pool settings to allow just 1 connection for whole application docs.microsoft.com/en-us/dotnet/framework/data/adonet/… , but then you should add retries and error handling implementation for every database access, because now it may fail due to timeout/lack of connection available.
– dlxeon
Nov 21 at 7:19




Actually, I'm a little bit unsure if concurrent database operations is root cause of issue, because databases are designed to handle lots of queries. But if you do believe that's the case, maybe you can tweak database connection pool settings to allow just 1 connection for whole application docs.microsoft.com/en-us/dotnet/framework/data/adonet/… , but then you should add retries and error handling implementation for every database access, because now it may fail due to timeout/lack of connection available.
– dlxeon
Nov 21 at 7:19


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53406692%2fconsumer-producer-producer-thread-never-executes-assigned-function%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

Refactoring coordinates for Minecraft Pi buildings written in Python