I have not used multi threading much for asp.net. I have a web application that uploads a large temp file to folder. I would like to take that temp file and do some other things with it after it is uploaded. Can I do this work on another thread without the user being on the website any more? Thanks for any help or suggestions.
1.User post large file
2.uploading temp to server
3.After upload completes. I would like to run another thread/worker that can run without any user iteration but is trigger by the user.
void uploading(){
//Uploading file To server
}
void Submitclick(){
Start a Thread
Thread thread = new Thread(DoThreadWork);// does the user still need to be logged in?
Send to another page
}
void DoThreadWork(){Do this in background}
It's definitely possible, I've used background threads quite a bit in ASP.NET to do some funky stuff. If you have complete control over the server it might be more elegant to run the background code in a separate application or a windows service.
It's a better separation of concerns to have your IIS app dealing with just responding to web requests, and it's not geared up for that.
Also a warning, if you have a background thread in ASP.NET 2.0 and it has an unhandled exception, the default is to reset the application pool.
More information here: http://blogs.msdn.com/b/tess/archive/2006/04/27/584927.aspx
// 3 downvotes?
Listen, it's not alway possible to avoid running something in a background thread. I've hit this in several situations:
I've worked in a company with an unreasonable attitude to software
where we were not allowed to deploy a separate app to handle the
background processing. I argued for a windows service, but was
overruled and told to implement it in a background thread. Obviously
I moved on from that company to a healthier environment, but that is
the reality is this you have to deal with unreasonable situations
sometimes.
if you're in a hosted environment you don't always have the option to offload onto a seperate process.
The question was if it is possible. I'm answering that question.
If you want to separate the uploading of file from website user interaction you can make a windows service that will contineously check that if file is ready for upload and upload the file.
You can use the thread pool for that. The sample code relies on the article in the following lik: http://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx
First write your method that does the work. The method must get 1 argument of type object:
public void DoWork(object threadContext)
{
}
than, in the place of the code that you want to call the method do:
...
var threadParam = ... // Put any value you want to be used by the DoWork method
ThreadPool.QueueUserWorkItem(DoWork, threadParam );
The method will be queued until the system will hav free thread to handle the work and execute the method regardless if the request has been ended or not.
Related
I have a file conversion app, whose main job is to read from an input file, process the data, save it in another input file.
This process is already organized as an asynchronous task working on two streams, in orderd to show a live progress bar while the conversion is done.
The issue I have now is that when the app is suspended, the conversion is suspended too, which is a problem since the files involved get quite big and users want to do else meanwhile.
What can I do to keep this task alive?
Use the Extended Execution API to postpone app suspension:
https://learn.microsoft.com/en-us/windows/uwp/launch-resume/run-minimized-with-extended-execution
Is there a way to monitor the state of a console application?
I am trying to build a user interface which shows whether or not a console application is currently running on the server (processing files). If it is running, I would like to show the current state: how many files processed, what file currently being processed, etc.
The only way that I can think of doing this:
Create a text/xml file when application is started
Update text file with information about current state for each object it processes
Delete text file when the application is finished processing
To me, this doesn't seem like a very good or efficient way to do it. Is there a way to detect if the ClickOnce application is running, and perhaps some other way to access the "Messages" or Log of it to show the progress?
Note - I am also looking into using NodeJS to do this, but unsure if it has this capability.
First, you should consider writing this as a Windows service instead of a console application.
That said, scraping a log file that your application is writing is a reasonable approach. Just ensure that it never gets too big.
Alternatively, you could look at using custom performance counters. That would open the door to using System Monitor/perfmon as your monitoring tool, so no need to write any client code.
There are at least two ways to achieve that:
Your console application writes some logs, some state files, during its run, so other processes can read those files and understand what is going on in that console process.
Implement an IPC mechanism. There are different ways to do that. It may help you look in What is the easiest way to do inter process communication in C#?.
What is a good way to run a time-consuming function from a C# webpage on the users CPU instead of running it on the web-server? Is it possible to get a C# function to run locally or do I have to write the function in JavaScript? The function itself is not secret in any way but I would prefer if the input and the output will be kept secret from the user. The solution should not require the user to download anything.
This functions uses data from the database + user input and when it's finished it writes the output to the database.
The functions best case is ~1s, average ~30s and worst ~10min (for every user) so it's not an option to run this function on the web-server.
You can get this to work, by either
coding the function in JavaScript
compiling the C# source to JavaScript (off the beaten track)
running the C# code in silverlight (done and done again, remember Java Applets? same science)
You won't really be able to keep the data totally secret, though.
Now, how to go about this... You will need a web service to provide the data to your silverlight component and another one to accept the computed results. You know, I don't really see why everyone else here thinks this is such a no-go...
As for data secrecy... The best you can do is obfuscate, though you should use a secure communication layer for aquiring the data and posting the results back, what ends up on the users computer will eventually be open for inspection by the user. If you use obfuscation techniques for your code, this will make reverse engineering an encryption/decryption scheme for the data payload harder, but you're playing essentially the same game as game devs / game crackers...
Personally, I would code the client side stuff in JavaScript. Chances are, what you want done is more of an algorithmic thing than a library thing, so porting to js should not be difficult to pull off.
You can't and shouldn't run arbitrary cs code on the user's computer. You also can't really run a long lived process in javascript on the client. User interaction with the page will be blocked and if they navigate to a different page it will stop.
What you should do is write a windows service to run these tasks in the background. Have a queue table where you save the input data from the web side, then have a service that polls the table for work and processes the input data.
You can't execute any C# code on the client computer when you they enter a webpage. You are correct in your assumption that you need to write it in javascript to execute it on the client.
This doesn't work. Web server does the processing. Unless you are doing distributed computing and stuff like that, it is not designed to work on a client. Client needs to download software to process stuff. Webpage is webpage. Text.
The only code you can run on the client is js.
That being said, you definitely don't want to run your function on the client if you have sensitive information involved.
I have an ASP.NET page that gets a list of game server ip addresses (quickly) and loops through them running a command line tool against them to get special game server information. I have to use the command line tool because I don't know how it works to get the information from the machines and I don't want to reinvent the wheel. The looping is the slow part (surprise surprise). Each command line tool run takes up to a second so with approximately 60 ip addresses polled on average, the page load can take from 30-60 seconds to render the results I need.
My obvious thought was "multithread that thing!" Well, I tried that w/ thread pools but ended up with a hanging website if more than one person accessed the page at a time. This was only using 4-5 calls at a time up to the 60 making it a 10 sec load time. So not only did it hang with multiple users, it was still too slow. I'd be happy if I could get it to under 3 seconds.
I should mention this page is in a shared hosting environment. I had a great solution before outside of the shared hosting environment but I had to cut costs and I'm trying to make it work w/ shared now.
Is there any hope?
You shouldn't really be polling these servers "on demand." It would be better to use ASP.NET to show the list of server information, and some other process - like a windows service, or scheduled task - to poll the servers every couple of minutes to generate that list. To summarize: The service would create an XML file (for example) and ASP.NET would display it to users. This way, the amount of users viewing the page does not affect the amount of times you try to poll the servers.
Update:
You need to ensure the process that pings servers is a singleton. Specifically, a singleton is a class in which only a single instance can exist. In more general terms for your case, you need to set a global flag that says "i'm currently pinging servers" and another global datetime value to says "the last time i pinged the servers was at hh:mm:ss" - you could use the Application dictionary to store the boolean flag and the datetime. Each time someone loads your page, check the flag to see if it's already pinging the servers. If it is, don't do it. If the flag says ok, then check the current time against the last time you did it. If it's less than 5 minutes, don't do it. All of this should be done in a background thread. This thread should update an xml file in App_Data. All requests to your pages should render this data immediately. A page request should never block. If the file is not there on the first call, then return "ping in progress, try again in 5 minutes." Follow?
Read about the ASP.NET Application state dictionary here:
http://msdn.microsoft.com/en-us/library/ie/ms178594.aspx
Low tech solution might be to call a bat file that makes each of the exe calls, instead of the exe repeatedly from asp.net. Saves the repeated shells to the OS overhead
Each call to the exe can pipe the results to a text file, which can then be read back all at once, once control returns to the asp.net app from the bat.
If the list of ip's change, then the the asp.net application could create the bat file before running it.
I am using a webclient to download a media file from my web server and save to isolated storage.
If you click a button it starts the download and save to Iso store process, but if you click the button while the file is downloading it tries to create a concurrent IO thread to download again and errors with webclient does not allow concurrent IO threads.
I want to write a conditional if statement to check if there is already a IO thread in being used but I'm not sure how I would do this.
Any help would be greatly appreciated.
Can't you just use a boolean to see if you started the download already? Either way it sounds like it would be better to actually disable the button in the UI after you start a download, and enable it again once it finishes or fails.
Your UI should be consistent with what users have the ability to do at a given time - letting them try something and then make them fail sounds like a frustrating user experience.