2012-06-02 29 views
13

Tôi đang cố gắng tìm ra lý do tại sao cuộc gọi WCF đầu tiên sau khi ứng dụng máy khách bắt đầu mất nhiều thời gian hơn so với lần thứ hai.Tại sao cuộc gọi khách hàng WCF đầu tiên lại chậm?

Tôi đã làm gì để kiểm tra rằng:

  1. thực hiện đơn giản tự tổ chức WCF Server và giao diện điều khiển của khách hàng.
  2. Máy chủ được làm nóng lên - Tôi chạy nó và gọi phương thức nhiều lần trước khi chạy thử nghiệm.
  3. Ràng buộc là basicHttpBinding để giảm chi phí bảo mật và mạng.
  4. Kịch bản thử nghiệm - bắt đầu ứng dụng khách trên bàn điều khiển, thực hiện hai cuộc gọi dịch vụ WCF giống nhau liên tiếp.

Trong thử nghiệm của mình, tôi thấy ~ 700 mili giây cho cuộc gọi đầu tiên và ~ 3 mili giây cho cuộc gọi thứ hai.

Gần như một giây dường như là quá nhiều thời gian cho trình biên dịch JIT. Tôi sẽ chấp nhận nếu thời gian đó được sử dụng để khởi tạo một số cơ sở hạ tầng phức tạp như ObjectContext trong khung Entity nhưng mã của tôi rất đơn giản và các lớp proxy đã được biên dịch.

Tôi cũng đã thử ràng buộc netNamedPipeBinding. Kết quả chứng minh mẫu - cuộc gọi đầu tiên mất ~ 800 ms, cuộc gọi thứ hai mất ~ 8 ms.

Sẽ đánh giá cao nếu có ai có thể giải thích tại sao cuộc gọi dịch vụ đầu tiên mất quá nhiều thời gian.

Đã thử nghiệm trong Win 7 64 bit.

Triển khai của tôi ở bên dưới.

hợp đồng:

[ServiceContract] 
public interface ICounter 
{ 
     [OperationContract] 
     int Add(int num); 
} 

Dịch vụ thực hiện:

public class CounterService: ICounter 
{ 
     private int _value = 0; 

     public int Add(int num) 
     { 
      _value += num; 
      Console.WriteLine("Method Add called with argument {0}. Method returned {1}", num, _value); 
      return _value; 
     } 
} 

Server thực hiện:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Uri baseAddress = new Uri("http://localhost:8080/Service"); 

     // Create the ServiceHost. 
     using (ServiceHost host = new ServiceHost(typeof(CounterService), baseAddress)) 
     { 
      host.Open(); 

      Console.WriteLine("The service is ready at {0}", baseAddress); 
      Console.WriteLine("Press <Enter> to stop the service."); 
      Console.ReadLine(); 

      // Close the ServiceHost. 
      host.Close(); 
     } 
    } 
} 

Server Configuration:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
    <services> 
     <service name="Server.CounterService"> 
     <endpoint address="base" binding="basicHttpBinding" name="baseDefault" 
      contract="Contract.ICounter" /> 
     <endpoint address="net.pipe://localhost/Service/netNamedPipe" 
      binding="netNamedPipeBinding" name="netNamedPipeDefault" contract="Contract.ICounter" /> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name=""> 
      <serviceMetadata httpGetEnabled="true" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
</configuration> 

thực hiện Khách hàng (CounterProxy được tạo ra từ dịch vụ tham khảo):

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 

using (var proxy = new CounterProxy.CounterClient(_endpointConfigurationName)) 
{ 
    output = proxy.Add(1); 
} 

stopWatch.Stop(); 
// Get the elapsed time as a TimeSpan value. 
TimeSpan ts = stopWatch.Elapsed; 

Chức năng này sẽ chứa mã gọi là hai lần liên tiếp.

Client Configuration:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
    <client> 
     <endpoint address="http://localhost:8080/Service/base" binding="basicHttpBinding" 
      contract="CounterProxy.ICounter" 
      name="baseDefault" /> 
    </client> 
    </system.serviceModel> 
</configuration> 
+0

lẽ tải/biên soạn đối tượng proxy lần đầu tiên xung quanh, các serialisers XML vv Nếu bạn xem cửa sổ đầu ra, bạn sẽ thấy một cái gì đó như "Loaded assembly x54fjfj3fj" mà là một khách hàng WCF biên soạn. –

+0

Tôi đổ lỗi cho kiểm tra an ninh và 100 bí ẩn khác. Có nhiều cách hơn nhị phân liên quan đến những gì đang được triển khai trong dịch vụ. Để gỡ lỗi dịch vụ sử dụng các bộ theo dõi trong cấu hình và truy cập nhật ký, chúng sẽ hiển thị các bước theo mili giây thời gian chính xác được sử dụng. Bạn sẽ thấy một cái gì đó như xác thực, bộ lọc, vv ngay cả khi bạn có tất cả mọi thứ hoạt động như ẩn danh. –

Trả lời

7

Thông thường cuộc gọi đầu tiên mất nhiều thời gian hơn vì trong cuộc gọi đó, Channel Factory được khởi tạo và chuẩn bị sẵn sàng cho việc liên lạc và thời gian đó.Việc tạo ra Channel Factory sẽ được lưu trữ và sử dụng lại trong các cuộc gọi tiếp theo và do đó thời gian sẽ ít hơn.

http://social.msdn.microsoft.com/Forums/en/wcf/thread/43f89088-546b-46b0-adf8-214deb1741bd

+0

Nhưng đề xuất này là dành cho phía khách hàng, nếu tôi hiểu chính xác. chúng tôi không thể làm bất cứ điều gì ở phía dịch vụ. Nó không phải là dễ dàng để nói mỗi khách hàng làm điều đó. – batmaci

+0

Có vẻ như Microsoft cuối cùng cũng đã kiểm soát được điều này: https://msdn.microsoft.com/en-us/library/hh160401%28v=vs.110%29.aspx – userx

2

Tôi có vấn đề tương tự. Vì vậy, những gì chúng tôi thực sự đã làm, chúng tôi đã viết dịch vụ gọi dịch vụ WCF cho một số khoảng thời gian. Tôi biết rằng nó không phải là một giải pháp thanh lịch nhưng nó hoạt động.

+0

Bạn có bất kỳ ý tưởng TẠI SAO nó đang xảy ra? Có vẻ như nhiều người nhìn thấy nó nhưng không ai tôi biết hiểu lý do. Cảm ơn cho phản ứng. –

+1

Nhìn vào điều này, cũng được viết http://www.codeproject.com/Tips/114132/WCF-First-Call-Slow – GutterStink

+0

Bạn đã sử dụng khoảng thời gian nào? Từ những gì tôi có thể nói, bộ nhớ cache dường như không bị ràng buộc với thời gian chờ. Nhưng ít hơn 1 phút. – userx

2

Nếu bạn đang thực hiện cuộc gọi tới dịch vụ WCF của bạn ít thường xuyên hơn 15 giây (chúng tôi quan sát cần phải chờ khoảng 20 giây trong ứng dụng của chúng tôi), blog của Microsoft này xuất hiện để giải thích vấn đề của bạn: http://blogs.msdn.com/b/wenlong/archive/2010/02/11/why-does-wcf-become-slow-after-being-idle-for-15-seconds.aspx

bài báo cũng liên kết với cụm từ này mà đề cập đến một bản sửa lỗi cho SetMinThreads() mà cũng dường như là một vấn đề góp: http://blogs.msdn.com/b/wenlong/archive/2010/02/11/why-are-wcf-responses-slow-and-setminthreads-does-not-work.aspx

2

tôi đã nhìn thấy sự chậm trễ trong khoảng 30 giây khi tôi lần đầu tiên được tạo ra ser của tôi ví dụ phó proxy mà tôi biết phải liên quan đến một số loại thời gian chờ mạng.

Cuối cùng, tôi đã thực sự kiểm tra Danh sách thu hồi chứng chỉ bị chặn hoặc thất vọng bởi proxy công ty (yay Websense) như được đánh dấu ở đây: WCF service startup too slow? Have you thought to CRL check?.

Để tham khảo trong tương lai và trong trường hợp liên kết đi chết nó đi xuống thêm dòng sau vào cấu hình client:

<configuration> 
    <runtime> 
    <generatePublisherEvidence enabled=“false”/> 
    </runtime> 
</configuration> 
+2

Trong .NET Framework 4 và phiên bản mới hơn, phần tử không ảnh hưởng đến thời gian tải lắp ráp. Để biết thêm thông tin, hãy xem phần "Đơn giản hóa chính sách bảo mật" trong Thay đổi bảo mật trong Khuôn khổ .NET.https: //msdn.microsoft.com/en-us/library/dd233103 (v = vs.100) .aspx (chuyển sang .NET 4.0) – Ludwo

Các vấn đề liên quan