Wcf faq (2)-winform host UI Blocking

Source: Internet
Author: User

When using WCF, there are four host methods used to start the service: console, winform, IIS, and Windows service. While winform acts as the host, it usually has its own UI display and operations in addition to acting as the host for some business needs. When doing this kind of application, it is often found that calling WCF will cause UI blocking, making winform on the server unable to operate normally.
The following is an example: Server UI1 sDisplays a system time data.5SCall the WCF Service to obtain and display the time data.

 
Look at the Code:
1. In WCF, service instances use single, getdata to simulate complex operations, with a latency of 5 s.
[Servicecontract] <br/> Public interface iservice1 <br/> {<br/> [operationcontract] <br/> string getdata (); <br/>}</P> <p> [servicebehavior (instancecontextmode = instancecontextmode. single)] <br/> public class service1: iservice1 <br/> {<br/> Public String getdata () <br/>{< br/> // simulate complex operations with a latency of 5 MB <br/> thread. sleep (5000); <br/> return datetime. now. tostring ("HH: mm: SS fff"); <br/>}< br/>} 

2. server and client code. (For ease, the server and client use a winform Application)
(1) server (_ host is a reference of servicehost)
Private void setsever () <br/>{< br/> _ host = new servicehost (typeof (wcfwinformhostlib. service1); <br/> _ host. open (); <br/> text + = "[server]"; <br/> timer1.interval = 1000; <br/> timer1.tick + = (S, E) ==>< br/>{< br/> var DATA = datetime. now. tostring ("server: hh: mm: Ss. fff ") + environment. newline; <br/> textbox1.text = Data + textbox1.text; <br/>}; <br/>}
(2) client (_ client directly uses the data contract to obtain remote object reference through channelfactory)
Private void setclient () <br/>{< br/> var factory = new channelfactory <wcfwinformhostlib. iservice1> (<br/> New nettcpbinding (), <br/> "net. TCP: // localhost: 20001/wcfwinformhostlib/service1 "); <br/> _ client = factory. createchannel (); <br/> text + = "[client]"; <br/> timer1.interval = 5000; <br/> timer1.tick + = (S, E) ==>< br/>{< br/> var DATA = "client:" + _ client. getdata () + environment. newline; <br/> textbox1.text = Data + textbox1.text; <br/>}; <br/>}
OK. Run it now to check the actual running status:
1. Start the server. At this time, the data is still normal, and a data record is displayed every 1 s.

2. Start the client, which is also a normal data record every 5s.

Let's look at the server. At this time, the data is no longer normal, and it is changed to 5s with the client. In addition, the drag-and-drop interface on the server also feels very stuck, and the UI is obviously blocked.

Start to find the cause. At first glance, you may find that it is a problem with instancecontextmode = single of the service. It turns out that even if it is changed to percall, it will not change, will the re-import mode be set incorrectly? No. The UI of the application on the concurrencymode. Multiple server is still blocked. After many debugging, it is found that the main cause of this UI blocking is servicehost. It is assumed that some listener operations started by servicehost will conflict with the message loop of the UI. (If you know the specific reason, please leave a message. Thank you ). Let's modify servicehost and throw it into a thread:

Add a threadservicehost class

Public class threadservicehost <br/>{< br/> const int sleeptime = 100; <br/> private servicehost _ servicehost = NULL; <br/> private thread _ thread; <br/> private bool _ isrunning; <br/> Public threadservicehost (type servicetype) <br/>{< br/> _ servicehost = new servicehost (servicetype ); <br/> _ thread = new thread (runservice); <br/> _ thread. start (); <br/>}< br/> void runservice () <br/>{< br/> try <B R/>{< br/> _ isrunning = true; <br/> _ servicehost. open (); <br/> while (_ isrunning) <br/>{< br/> thread. sleep (sleeptime); <br/>}< br/> _ servicehost. close (); <br/> (idisposable) _ servicehost ). dispose (); <br/>}< br/> catch (exception) <br/>{< br/> If (_ servicehost! = NULL) <br/> _ servicehost. close (); <br/>}< br/> Public void stop () <br/>{< br/> lock (this) <br/>{< br/> _ isrunning = false; <br/>}< br/>} 
Modify the startup code of the server:
_ Host = newThreadservicehost(Typeof (wcfwinformhostlib. service1 ));
 
Start the server and client again, and the operation is normal.
Server: one piece of data per 1 s, client: one piece of data per 5S.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.