C# use multithreading or run as separate application? - c#

I have a windows application that reads from a database and populates multiple Listview containers depending on what items the user selects. Some of the data in a particular Listview is right-clickable with a MenuItem option to ‘Write Data to Excel’. This may take around 10 minutes to complete.
I have the Excel Interop portion written in stand-alone code or can I incorporate it into the application project. The Excel Interop app takes only 1 parameter to do its thing.
My question is… should I incorporate it into the Windows App and use multithreading or run it as a standalone app (which seems more efficient), which is called from the Windows App? And what is a good way of doing that where the Windows app starts the process and then can forget about it.

I think that the answer for this one is answered by the question : "What should happen if the user closes the main application during those 10 minutes ?"
If the file should still be wrote, then a standalone application is perfect, cause your threads won't survive.
If the file creation should be interrupted, then I see no reason not to use multithreading, as it seems simpler by default, in particular debugging this part of the code is way easier if it's in the same application.

I would recommend for the below flow:
We can create our own queue which will be either maintained in database or file system.
Then we can write a scheduler which will fetch all the unprocessed request and with the respect to response mark appropriate status of queued item.
Now You application can just call the queuing process and move forward from there.

Use another thread to write it.

Related

How to control a separate WPF application?

I'm developing a Revit add-on which performs some lengthy tasks. During the process, I want to display a simple WPF window with an indeterminate progress bar, a label to inform about current process and a button to enable aborting.
I already tried the most obvious ways of accomplishing that: creating a WPF window inside the add-on and displaying it, but the problem is that the UI gets frozen, no matter how I implement this. During some processes, the whole Revit UI gets frozen/white so I really wouldn't expect my embedded WPF window would behave normally in these conditions anyway.
The workaround I figured out was to have the WPF window as a separate app (EXE file) I could run from the add-on. I based my implementation on this example .
The good part of it is that it doesn't hang no matter what is happening with Revit.
The bad part is that the sequence of how Windows is queuing the calls of my separate WPF app is sometimes different from the sequence of these calls from my add-on. It sometimes results in a situation when the Revit process is over but the WPF window is still displayed (waiting for the final, closing call which had been apparently already executed, but then the app got reactivated with another, delayed call).
Preferably I would like to handle the WPF app the same way as you can i.e. handle an Excel application from .NET. You create an ExcelApp object, do what you want with it and dispose of in the end.
The problem is I don't have a clue of how to do this.
How should I expose the WPF app's API to my add-on?
Could it be possible to have the WPF app responsive and controlled from the Revit add-on at the same time? (user can still click the abort button, the indeterminate progress bar doesn't freeze)
The First thing to know is about interacting between two processes. there are some Standard approaches:
Interacting through Socket (Socket Programming)
Using Named PipeLines (Useful when your messages aren't so long)
There are some other predefined Libraries based on above techniques. Using a FileSystem Based method is not a reliable way to proof the outputs.
This was a part of your solution. The next step is to use Threading in your WPF application. I'm not familiar to Revit and I don't know how it works.
UI freezing is normal in a long running process. because UI is busy and it can't answer your requests (e.g Mouse Move, Click, ...). So using a Thread you can put your long running process into a separate place and wait for the response at the end of it.
There is a problem while using a Thread. Because you left your UI and started your long running process on a separate Thread, you can't directly access to your ProgressBar. In this situations you have to use ThreadDispacher. It's not a terrifying concept, it just a three line of codes that will adds to your callings.
for example:
Dispatcher.Invoke(() =>
{
ProgressBar.Value++;
});
Search for a Library to doing your IPC (Inter Process Communication) to get the result faster (or you can learn about above techniques to do it by your means) and next add a simple thread to your WPF application so you be able to Start, Pause and resume the running job based on the situation.

Difference between Console App vs Win Form App in context of performance?

I have a console application that shows latest activities & status on its console. The application is heavily threaded & performance is the major concern. No user interactivity is required. Due to a recent case, ive been asked to migrate it to a win form application.
Initial post ->
How to programmatic disable C# Console Application's Quick Edit mode?
So to encounter the problem, I have used Application.Run(ApplicationContext context) so to start a message loop in my console application so that i can hook and trap mouse events and can reset quick edit mode at runtime. I have also deleted a Console's default menu item "Edit" that emerges on right click so not to allow the user to Mark/Copy/Paste.
I want to know what should be the optimal solution, migrating to win form or console app (considering changes i made). Also i need to call Invoke every time in order to put the task in UI's queue so to print the message if migrated to winform.
WinForms would definitely give you more flexibility in what you can do with the UI.
In terms of performance, you really need to be doing a lot of UI updates in order for performance to be a concern. It sounds like that will not be the case since you're currently getting it done with a console application. Most of the time, the UI performance is affected not because the UI thread can't keep up with the updates, but because non-UI stuff (e.g. file IO, database queries, etc.) is done within the UI thread.
I would consider to change your application so that it streams it's output into a logfile, a lightweight database or a Windows event log instead to the console. Thus your application won't need a console or UI at all and can be alternatively run as a service. If someone wants to see that messages, give him a separate (probably Winforms) program to view the latest output, or if you use the Windows event log, he can just use the Windows Event viewer to check the output of your program.
So you neither have to migrate you application to Winforms, nor do some ugly console hacks.
To process log files, the Microsoft log parser may be of interest for you.

Client side communication with Windows application

I have a web-based picking/packing solution for delivering orders (asp.net/c#). Orders are marked as packed in the browser and then immediately the label information is added to our database, ready for the next part...
The label printing is done via a Windows application (written in C#) and was done this way because I couldn't find a way of getting the browser to print the label automatically (i.e. without the user having to click Print/OK, etc.)
The problem:
The Windows application polls every 10 seconds (subject to change) to see if there are any new labels for that picker/packer. Now, if I could get the browser to communicate with the label application then the polling would be unnecessary, since the picker/packer would have just clicked "Ready to Ship" and the label data would be created.
The data that is pulled down by the polling process isn't vast, but I'm concerned that as we add more picker/packer stations the polling process could have a knock on effect to the web server/database (since all stations would be polling). Also, pickers/packers don't want to wait around waiting for labels, so extending the polling time isn't possible (if anything I'd like it as quick as possible)
Solutions?
So, ideally, I'd like a way of communicating between the browser and the application (if possible). Or any method that removes the need for polling. Perhaps something akin to Comet, that allows the server to send a message to the application when a new label is added.
Ideally, a solution that wouldn't require a specific browser. But this may be asking too much.
A long-term solution would be to move the web-based picking-packing solution into the label application, but that would be a lot of work!
I hope that's clear and not too wordy. Let me know if I can add any other details in here. Thanks in advance.
Edit
Am looking into websockets as an idea. Any advice will be more than welcome!
Update
Thanks for all comments. I've now got a few ideas on how to solve the problem:
Websockets. May be problematic with firewall issues since I don't have easy access to the system (geographical distance)
Read browser cookies from the application. Possible solution http://www.codeproject.com/Articles/330142/Cookie-Quest-A-Quest-to-Read-Cookies-from-Four-Pop. This covers all the browsers that are in use in the warehouse. I can poll the local cookie values and see if any new labels have been created, then download them. Therefore no polling on the database server.
ActiveX control. Limited to IE and perhaps there'd be some security/setup issues with installing this on each PC.
Leave the code as is. Gauge whether the load on the database server is too much or ok.
You could create a local WebSocket server in your C# application and then make the browser connect to it and send the data you need to print.
I'm not sure, though, that this is what you need. As I see it you need to pass graphical data to your application, which could be really tricky to do using only javascript.
The appropriate way to achieve the communication between a web application and a desktop application would be to go through a server both apps talk to.
You can get any web-server (e.g. node.js nodejs.org that will let you use the same javascript you use for the web-app on the server) and interact with it. How you talk with the server from the desktop app depends on its technology. However all languages have some way to do http communications like SOAP.
Or you can try to make:
Both apps talk to the server using socket.io. You can borrow code from the following project.
Create an MSMQ (or a queue implementation of your choice) and host a WCF service in your windows application that polls the MSMQ.
Have your ASP.NET application write any relevant information to this queue so that the WCF service in the windows app that pulls this information will know what to make of it and print your labels.
The reason I mention a queue is for reliability, if your windows app goes down for any reason, the queue will at least be preserved and waiting for you to bring the windows application back up.
Although there is a bit of polling involved, it is very quick and almost neglibible. Implementing it is automatic with NetMsmqBinding, it's all taken care of. All you need to do is configure it.
If you go for a non-MSMQ queue, then I don't know whether you can still use NetMsmqBinding, you may have to create your own.
I'm not sure, but it seems like your application is polling a filesystem for these new labels to print? Have you considered using a FileSystemWatcher in your application? You can set that to watch a directory and be notified of anything new.

Run C# application as scheduled task

I have a C# application that was designed to run with a windows form but now needs to run as a scheduled task. I have had problems with this and I think it is because it needs to be "headless" in that it should have no concept of a user environment. The program has been written to run unattended in that it has an /AUTO arg which then will run from some defaults but the form is still shown which causes the problem.
I have looked around and I think there is a way to suppress the form in this situation but I can't find exactly how. Does anyone know how I can suppress the form and allow this application to run?
Take the logic required for the scheduled task out of your WinForms application and put it in a Console application. If you can reuse logic both places, move it into a shared library.
Convert your application to console mode and also check the "Hidden" checkbox in the 'General' tab of Task scheduler.
This will help you
Still if you want to use the WinForm application, then set its ShowOnTaskbar property to false.
And its very easy to convert your winform application to winform one. Just go to the project properties and change the output type to Console. But you need to do few tweaks in the code.
Check if the /AUTO parameter is set and then depending on whether or not is is. Change this in your Program.cs:
Application.Run(new Form1());
to
Application.Run();
this won't show a form and you can do whatever other things you like.
This is the best I can give you without having seen you code. Hop it helps!
You can tell the task to interact with desktop in which case a form that shows is not a problem. As long as your app will close by itself so the job finishes..
I made a form based thing and then wanted a scheduled task so wrote a commandline front end calling the form based app, and then pushed the 2 exes together with ilmerge so it cant get confused, because it was a cheap hack
If your code is properly written you can do an exe front end and use the same classes as your form (or dll) and work that way.
As far as I understood you, you do not need the Forms mode anymore, right?
If this is correct, I suggest implementing your application as service, e.g. a WCF service. It can permanently run and execute your business logic on a configured timer.
To make configuration of the timer easy and flexible, you could optionally imncorporate NCronTab. This allows you to schedule the task in a pattern as easy as 45 11 * * Friday (=> "Run every Friday at 11:45 am")

Prevent application launch in C#

Okay I've spent the afternoon researching and haven't had much luck finding the answer to this. I am trying to prevent an application from launching via some sort of dll or background application. It is to be used in monitoring application usage and licenses at my institution. I have found leads here regarding WqlEventQuery and also FileSystemWatcher. Neither of these solutions appear to work for me because:
With WqlEventQuery I was only able to handle an event after the process was created. Using notepad as a test, notepad was visible and accessible to me before my logic closed it. I attempted to Suspend/Resume the thread (I know this is unsafe but I was testing/playing) but this just hung the window until my logic finished.
With FileSystemWatcher I was not able to get any events from launching a .exe, only creating, renaming and deleting files.
The goal here is to not let the application launch at all unless my logic allows it to launch. Is this possible? The next best solution I came up with was forcing some type of modal dialog which does not allow the user to interact with anything, once the dialog is closed the application is killed. My concern here is killing the application nicely and handling applications with high overhead when they load such as Photoshop or something. This would also interfere with a feature I was hoping to have where the user could enter a queue until a license is available. Is this my best route? Any other suggestions?
Thanks
edit: To clarify this is not a virus or anything malicious. It's not about preventing access to a blacklist or allowing access through a whitelist. The idea is to check a database on a case by case basis for certain applications and see if there is a license available for use. If there is, let the app launch, if not display a dialog letting the user know. We also will use this for monitoring and keeping track if we have enough licenses to meet demand, etc. An example of one of these apps is SPSS which have very expensive licenses but a very limited pool of people using it.
Could you use
System.Diagnostics.Process.GetProcessesByName
in a loop to look for the process?
It might work if you don't use too aggressive a polling rate.
You are indeed close, take a look at the WMI Management Events. http://msdn.microsoft.com/en-us/library/ms186151%28VS.80%29.aspx
Sample code from Microsoft: http://msdn.microsoft.com/en-us/library/ms257355(VS.80).aspx
Subscribing to the appropriate event will provide your application with the appropriate information to perform what you described.
Not sure if this is a GOOD solution but you could do something like pass a key into main so that if the key is not present or valid the application shuts down. Then when you open the application in your code, just pass the key in. Someone would then have to know the key in order to start the application.
This is assuming you have access to the application in question's source code, which upon reading your question again, I'm not so sure of.
I assume you don't have source for the application you want to prevent from loading...
Have you considered using a system policy? That would be the best-supported way to prevent a user from launching a program.
You could have a service running that force-kills any app that isn't "whitelisted", but I can't say how well that would work.
I wonder if you are taking the wrong approach. Back in the day there was a Mac app that would prevent access to the desktop and had buttons to launch a set list of applications.
IDEA
What if you had a wrapper for the approved apps then only allow your wrapper to run on the computer?
I would expect there is some way of hooking an application launch, but can't help directly on that front.
You may be able to improve your current approach by detecting the application's window opening and hiding it (move it offscreen) so that the user can't attempt to interact with it while you are trying to shut it down.
However, another approach that may be possible (depending on your circumstances) would be to write an application launcher. This simply is a replacement for the shortcut to the application that checks your licencing conditions, and then does a Process.Start to launch the real .exe at that point. This would work well for any application. (I used a system like this for starting up applications with specialised environment settings and it works beautifully)
You could combine this with your current approach as a fall-back for "clever" users who manage to circumvent your launcher.
If my understanding is right you want to create an application what will prevent the computer user to start any other process except ones for a white-list.
If this is the case, monitor the process list of processes (in a while loop) using System.Diagnostics.Process (the GetProcesses method gives the list of all running ones)
Just kill the process when it starts.
Or if your machines have Windows 7 (Windows 2008??) you can use AppLocker. http://www.microsoft.com/windows/enterprise/products/windows-7/features.aspx#applocker Just let Windows prevent the startup.
You might want to look at this product: http://www.sassafras.com/licensing.html Personally I can't stand it, but that's because it does what you describe. Might save you some coding.
You could actually edit the registry so when you click a psd, your launcher gets called instead of photoshop. Your launcher then checks for licenses and if there is one starts photoshop with the path of the file.
This is a long shot but you may find it helpful.
Perceived Types and Application Registration
http://msdn.microsoft.com/en-us/library/cc144150(VS.85).aspx

Categories