I am in need of some guidance on a project I am working on. We are looking for a replacement for CORBA server setup. In a nutshell we currently run a CORBA deamon service that hosts 10 instances of a C++ exe that is the entry point into our calculation process. The C++ code hooks into a bunch of different .net and C++ dlls and OCXs via COM. We also have another version of the executable that is compiled as a .dll that we are able to call in a similar fashion but it is only a single instance system so all is well there.
We are now looking to replace the CORBA components with a WebAPI so I have put together a basic ASP.net webAPI project that is able to process the requests into this C++ dll. Again, this works great when it only needs to handle 1 request at a time. Things start going sideways when I start testing concurrent requests. The request come into my handler just fine and I can see the 5 requests (I have logging everywhere tracking whats going on,) and each thread creates an instance of the dll but they are run synchronously.
What I have figured out is that even though there are multiple threads going in the ASP.net handler, the dll is STAThreaded (this is confirmed in the code) so the calls are queued up and only processed 1 at a time. My guess here is because the threads are all inside the same process the dll treats all the threads as the same apartment (STAThread) and causes the queue.
I have tried different async/await and task.run code and I can see different threads but it still comes down to the same process which makes the dll run synchronously. I did try change the dll to be MTA by changing the CoInitializeEx(NULL,0x2) to CoInitializeEx(NULL,0x0) but that didn't seem to change anything.
I am now running out of ideas and I don't think changing to use the .exe version and spawning multiple process is going to work because there is the CORBA stuff that allows a return object to be created and communicated back to the calling code. I need to be able to get the objects that are created in the exe to send back in the request.
Sorry for the long post, hopefully someone will take the time to read this wall of text and have some ideas of what I can try.
Thank you!
I would suggest that the WebAPI architecture is a poor solution to your problem. Typically you do not want to spawn long-running or blocking processes from ASP.NET, because it's quite easy to exhaust the threadpool and prevent the server from being able to handle new requests.
If you do want to continue having a WebAPI endpoint, I would start with taking the requests and putting them in a queue, and having the client poll or subscribe for the completed result.
You may be interested in looking a what they're doing with gRPC in dotnetcore 3.0 - if you want to keep that kind of architecture, but update the platform.
You can create multiple app domains. App domain is "It can be considered as a Lightweight process which is both a container and boundary" ref. Load your DLLs into that different domains. This way every app domain you create will load your COM DLLs separately. Create proxies using MarshalByRefObject as used here. Write an orchestrator that distributes requests to app domains and get the results from appdomains and send responses. Keeps tracks of which domain is busy which is not or create new domains for the request.
Also different methods mentioned in this link
Related
I am trying to write an app which would wake up on-demand as the messages are queued in MSMQ, do some processing and go back to sleep. Now I am expecting only ~20 messages per day, so keeping a process alive 24/7 just to watch the queue may not be a good idea.
The COM+ Queued Component came to my mind and I am nostalgic now. I could create a dll and register it with RegSVC() and set it up under Component Services to be Queued. But there are a couple of problems with this.
I don't like the way ".NET Serviced Components" are deployed (RegSVC)
Microsoft is showing the following warning on their page about Queued Components
This document may not represent best practices for current
development, links to downloads and other resources may no longer be
valid. Current recommended version can be found here.
ArchiveDisclaimer
For those who don't know how Queued Components work (just a little summary)
You create an object of a component, and call a few methods. The methods weren't actually called, but a "Recorder" recorded what you did and placed them in an MSMQ Queue. Later on, when its your turn; the "Player" plays your method calls. Your component does not have to be awake 24/7 taking up CPU and Memory just to wait for messages.
Is there anything similar in .NET now?
Well you can implement a queued component in .NET...
https://msdn.microsoft.com/en-US/library/6b617zws(v=vs.80).aspx
If you're looking for a more modern approach, it's not .NET as such, but perhaps checkout...
http://gruntjs.com/
I need to build a web application (MVC) that uses a third-party win32 dll as gateway for all business logic (contains logon-mechanism, functions and maintains some state).
This dll is not designed for multithreading. In an MTA scenario, the dll stumbles after a certain time.
The recommended solution is to run ASP.NET MVC in ASP-Classic Mode (STA using an Asp-CompatHandler). I tried this with success - everything runs stable.
The probblem is, there will be a lot concurrent users and some of the function calls takes some seconds (up to 10 secodns!). This will get horrible if all users block each other.
What would be the best approach to minimize the blocking-effects within the same application? Say only ten users should block each other?
It would be nice if:
...the web runs in MTA
...the web is just deployed once
...everything runs within the same process
Can anyone give me some advice for a good concept solving this?
Thank you! Martin
Update - Found a Solution:
Thanks to the "Smart Thread Pool" from Ami Bar I could accomplish the behavior I was looking for (easily). I implemented a worker concept (a specific amout of users share a worker and block each other in this worker), and for each worker, I have now my own thread pool instance with a max and min number of one thread. Well, it's not the idea of a thread pool, but it makes it very easy to handle the work-items and it also has some nice other features. The web application is running on MTA now.
I'm going to prepare some load tests to see if its stable over hours.
see here: http://www.codeproject.com/Articles/7933/Smart-Thread-Pool
The answer is very simple, although I don't think you will like much: you cannot use something that is not designed to be used in a multithreaded environment in a multithreaded environment.
2 possibilities:
Live with STA
Replace the single threaded COM object with something that is intended to be used in a web application
Unfortunately, if the dll is not designed to be used with parallel requests, you cannot use it with parallel requests.
The only solution I see for you to increase the number of concurrent users without having the application running parallely is to have multiple instances of the application running at the same time, with maybe a load balancer in front of them to dispatch the queries.
I am testing a SOAP service using a client generated in VS2010 via "Add Service Reference".
I am running tests in parallel (c. 10 threads) and this has exposed some DB locking issues in the system under test. However, this is not going to be fixed straight away and I don't want my functional tests failing due to this problem.
As a result I have reduced by test threads to 1, and as expected I do not see the locking issue, however, this obviously makes my test suites a great deal slower. Therefore I was wondering if it is possible to use client configuration to restrict the client to only make one request concurrently?
Its not the soap client that needs to be restricted its the calling code. A Soap call will be performed in which ever thread it is being made from. If you have a problem with multiple threads this is because you have multiple threads in your code, or you are trying to make additional service calls or updating something in a callbacks without understanding what thread you are in.
Depending on the problem you have many solutions which could include:
Remove the multi-threading from your application, don't use callbacks and don't fire up additional threads.
or ideally Make sure you dispatch back to the UI when appropriate, understand which thread you are in so you fix the underlying locking problem
http://msdn.microsoft.com/en-us/library/ms591206.aspx
Me.Dispatcher.BeginInvoke(Sub()
' This will be executed on the UI Thread
End Sub)
It would be nice (and very useful) to have the code in question..... in your question. Which version of .net your using and what your app is written in (Asp.net, WinForms?) would also help get some context.
NB: Sample code in vb.net but you get the idea ;p
I have a .NET 4 web application that has 3 separate projects associated – DAL, BAL, and UI. I am using Entity Framework for database interaction.
I have code that cycles through a bunch of database data, calls methods depending on what it finds, and then updates a database. I want this code to run all the time. At the same time I want users to be able to log in and run reports etc all while the code in the background is constantly running.
What is a good approach to this? Do I create a service for the code that constantly runs, a separate thread, an entirely separate project for the code that runs constantly, or a different approach..?
Also, depending on the answers given, how would I kick start the code that runs constantly? i.e. just through form load method or is there a better approach? I currently kick start the code by clicking a start button; this is fine for testing, but not going to work when in production.
You would be best suited for using Windows Services for always-running tasks.
Running code on a separate thread under IIS is not a reliable mechanism since IIS can terminate threads at will to conserve server resources.
Given your question and clarifications on other answers that:
Your solution runs in a hosted environment where you cannot install a service;
Calling it from a third server (i.e. Azure or such) is not an option for you;
You might be best off starting a thread in your Application_Start event to manage the database work. You'd probably want to ensure that this thread had some periodic idle time, so as not to take up too much of the hosted environment and ensure it's shutdown when your application ends or is restarted.
A service would really be optimal, but if you're in a hosted environment and can't/won't use another server, then that's not possible.
Use a Windows Service. Should also look into using Stored Procs for the database interactions you mentioned. In terms of kicking the Windows Service off, you can set it to automatic startup (when the OS starts) which will mean it will run until terminated.
I would only recommend a Windows Service if it will literally always be running. However, "always" usually means every x seconds / minutes / hours /days.
If x is greater than a few minutes, I would make it a Console Application and run it through the Windows Task Scheduler. This way you don't have to worry about memory leaks and a slew of other issues.
However, if it is only working with the database, I would recommend a stored procedure and a Sql Job.
Sometimes there is a lot that needs to be done when a given Action is called. Many times, there is more that needs to be done than what needs to be done to generate the next HTML for the user. In order to make the user have a faster experience, I want to only do what I need to do to get them their next view and send it off, but still do more things afterwards. How can I do this, multi-threading? Would I then need to worry about making sure different threads don't step on each others feet? Is there any built in functionality for this type of thing in ASP.NET MVC?
As others have mentioned, you can use a spawned thread to do this. I would take care to consider the 'criticality' of several edge cases:
If your background task encounters an error, and fails to do what the user expected to be done, do you have a mechanism of report this failure to the user?
Depending on how 'business critical' the various tasks are, using a robust/resilient message queue to store 'background tasks to be processed' will help protected against a scenario where the user requests some action, and the server responsible crashes, or is taken offline, or IIS service is restarted, etc. and the background thread never completes.
Just food for though on other issues you might need to address.
How can I do this, multi-threading?
Yes!
Would I then need to worry about making sure different threads don't step on each others feet?
This is something you need to take care of anyway, since two different ASP.NET request could arrive at the same time (from different clients) and be handled in two different worker threads simultaneously. So, any code accessing shared data needs to be coded in a thread-safe way anyway, even without your new feature.
Is there any built in functionality for this type of thing in ASP.NET MVC?
The standard .net multi-threading techniques should work just fine here (manually starting threads, or using the Task features, or using the Async CTP, ...).
It depends on what you want to do, and how reliable you need it to be. If the operaitons pending after the response was sent are OK to be lost, then .Net Async calls, ThreadPool or new Thread are all going to work just fine. If the process crashes the pending work is lost, but you already accepted that this can happen.
If the work requires any reliable guarantee, for instance the work incurs updates in the site database, then you cannot use the .Net process threading, you need to persist the request to do the work and then process this work even after a process restart (app-pool recycle as IIS so friendly calls them).
One way to do this is to use MSMQ. Other way is to use the a database table as a queue. The most reliable way is to use the database activation mechanisms, as described in Asynchronous procedure execution.
You can start a background task, then return from the action. This example is using the task Parallel Library, found in .NET 4.0:
public ActionResult DoSomething()
{
Task t = new Task(()=>DoSomethingAsynchronously());
t.Start();
return View();
}
I would use MSMQ for this kind of work. Rather than spawning threads in an ASP.NET application, I'd use an Asynchronous out of process way to do this. It's very simple and very clean.
In fact I've been using MSMQ in ASP.NET applications for a very long time and have never had any issues with this approach. Further, having a different process (that is an executable in a different app domain) do the long running work is an ideal way to handle it since your web application is no being used to do this work. So IIS, the threadpool and your web application can continue to do what they need to, while other processes handle long running tasks.
Maybe you should give it a try: Using an Asynchronous Controller in ASP.NET MVC