I encountered a problem a few days ago. I need to call a WebService in the page logic to process a time-consuming operation, but I don't need to know its return value. So I hope Asp.net can use the automatically generated WebService Asynchronous Method like winform
Do you want to say: when WebService is called on a page, isn't it enough to call its asynchronous implementation directly?
This is actually not feasible. In order to implement asynchronous calls, we need to make small changes to the page, add async = true to the page element.
We will soon find the problem:
Let's test it. Now we put a thread in the helloworld method of a WebService. Sleep (10000), and then calls its asynchronous implementation. Through debugging, we can find that althoughProgramWhen running to helloworldasync, it returns quickly and runs down. However, when all logic processing is complete, the page does not respond, but it waits until our thread wakes up before returning.
But what if I want to make the call?
You can use thread or threadpool to start a thread on your own. I recommend using threadpool. In this way, these threads will be managed by the IIS thread pool and will not cause a crash.
Let's analyze the characteristics of the two models.
Asynchronous mode of WebService
The main thread calls the subthread to execute a time-consuming operation (work1), simultaneously executes a series of synchronization operations (W2. .. W5), and then returns the result to W1.
This mode is suitable for scenarios where work1 returns, and in order to give work1 sufficient working time, the earlier the asynchronous call process starts, the better. For web program designers, here is a very important issue: thread occupation ..
As we mentioned earlier, every request in Asp.net will have a thread to process, but the available threads are limited. The server will use a thread pool to manage threads. When the thread is exhausted, okay, new requests can only be queued. For Web developers, threads are a valuable resource. Therefore, this solution increases the risk of exhausting the thread pool while processing them in parallel, after all, a request creates multiple threads.
The Mode Implemented by the thread pool is
This mode is suitable for non-return cases. In this case, the call to the sub-thread should be as late as possible. We can see that the longer the coexistence of the main and sub-threads, our scarce resource thread is safer. Please note that the total execution time may not be less than the synchronization time, but we will return the user interface soon, so the user experience can be improved.
Disadvantages of using web multithreading:
After reading the above description, you may say, simply change all my calls to asynchronous calls. Even if you do it, it is definitely a disaster, because at the same time of Asynchronization, a new thread will be generated to wait for the call to return, even if the return value of the function you call is void, therefore, the negative effect of asynchronous calls is that many sub-threads are generated, so note that when your call is very time-consuming, this sub-thread will also occupy your thread pool for a long time, if a large number of such calls occur, all available threads will be consumed.
Under what circumstances is the multithreading mode suitable for the web?
Let's take a look at this section.CodeHis purpose is to submit a report, pass in a report, get some report content from a WebService, insert the database, and generate a report file on the file server, finally, let's go through this method one by one to see where it is suitable for asynchronous calls? (Remember that our discussion is based on Web. For the multithreading of desktop applications, refer to multithreading Summary 1)
Public void createreport (Report report ){
// Obtain some information about the report from WebService. If the report is not obtained, the report is incomplete and cannot be submitted.
Report fullreport = callwebservice (report );
// Insert a database, which is very important.
Insertintodatabase (fullreport)
Try {
// Generate a report file. This is a time-consuming and error-prone operation.
Writestaticfile (fullreport)
}
Catch {// record the error log ....}
// This is only an email notification.
Callmailservice2 (fullreport)
}
The first statement callwebservice () loads some report content from a WebService. This is related to the business logic. If it is not loaded, the report content is incomplete and cannot be submitted, obviously, it cannot be changed to asynchronous mode. Here you can try Mode 1, but this change does not work because all other processes, including database insertion, reports are generated based on the returned results of this method. Therefore, if we use Asynchronization here, all other operations must wait for the returned results. Therefore, we use Asynchronization to add more threads, no time can be saved.
Let's take a look at inserting a database, and there is no need to use Asynchronous calls like above.
It is interesting to generate a report. It is indeed an operation that is closely related to the logic. However, by analyzing the code, we can see that although report generation is an important business step, however, it is not strictly stated that "if the report cannot be generated, the above operations must be rolled back". If the operation fails, the catch only records logs, there is no logic to be rewritten (it is very likely that another program or someone will regularly view the log and re-generate the file if an error is found). That is to say, in terms of this Code, generation can also be considered as an additional logic, so it can also be asynchronous. but: tens of millions of attention !!
Because it takes a long time to generate a report, The subthread that generates the report runs for a long time and cannot return to the thread pool for a long time. If the request volume is too large and the frequency is too fast, the thread resources will be exhausted.
In all fairness, this problem is not caused by Asynchronization. Even if it is called synchronously, it will take a long time for fertilizer to execute this operation. The call volume is too large and the frequency is too fast, which will also cause queuing. in addition, because the return time is too long and the user experience is not good, our transformation should be beneficial.
(Note: When I discuss this idea with a colleague about report generation, he thinks there should be a write queue in this place, obviously, the file generation speed does not match other processing speeds. This is indeed a reasonable practice)