2008-11-06 28 views
6

Tôi có một ứng dụng có kiến ​​trúc cơ bản sau:Làm thế nào để gỡ lỗi cuộc gọi từ xa .NET?

Dịch vụ cửa sổ (Dịch vụ) đăng ký loại .NET (RemoteObject) để truy cập từ xa (.NET Remoting). RemoteObject tạo ra các luồng không phải ThreadPool sử dụng ThreadPool để xử lý IO. Kích thước của ThreadPool phải được giới hạn ở một giới hạn cho một lý do cụ thể. Một ứng dụng GUI sử dụng .NET Remoting để truy cập RemoteObject.

Tôi đã nhận thấy rằng nếu kích thước của ThreadPool quá thấp, ứng dụng GUI sẽ treo khi thực hiện cuộc gọi đến RemoteObject.

Câu hỏi của tôi là, làm thế nào tôi có thể tìm ra lý do tại sao điều này bị treo và tại sao luồng RemoteObject bị ảnh hưởng bởi ThreadPool?

Điều này khiến tôi phát điên; cảm ơn sự giúp đỡ của bạn!

+0

Vâng, bạn nói "RemoteObject tạo luồng không phải ThreadPool sử dụng ThreadPool để xử lý IO". Đây không phải là lý do (ví dụ, các chủ đề không ThreadPool đang chờ đợi các khe ThreadPool để mở ra)? – Alan

+0

Tại sao điều đó ảnh hưởng đến chuỗi mà RemoteObject đang bật? GUI thậm chí không thể vào được phương thức RemoteObject mà nó đang gọi. – Chris

+0

Nếu bạn có thể có thể vung cái này, mương từ xa cho WCF. – Will

Trả lời

4

Nó chỉ ra rằng cơ sở hạ tầng .NET remoting sử dụng .NET ThreadPool (hoặc chia sẻ tài nguyên cơ bản), vì vậy các cuộc gọi từ xa có thể treo nếu tất cả luồng ThreadPool đang được ứng dụng của bạn sử dụng.

2

Điều này có thể không đặc biệt hữu ích nhưng tôi sẽ quăng nó ra khỏi đó.

Khi gỡ lỗi dịch vụ và ứng dụng khách nói chuyện qua tính năng truy cập từ xa, tôi thường sẽ chạy hai phiên bản trình gỡ rối: một cho trình khách và một cho dịch vụ. Chỉ cần được rõ ràng, tôi đang chạy hai bản sao của studio trực quan. Đối với dịch vụ, bạn có thể sử dụng lệnh đính kèm hoặc bạn có thể thay đổi trực tiếp và bắt đầu cuộc gọi (bỏ qua tất cả mã dịch vụ).

Đây là cách tôi thường bật gỡ lỗi bằng cách thay đổi chính, bạn sẽ phải và cuộc gọi DebugService đến dịch vụ, nó thực sự chỉ là một điểm vào mà các cuộc gọi bắt đầu. Một khi tôi có điều này tôi chỉ cần kích hoạt dịch vụ gỡ lỗi bởi definine SERVICE_DEBUG hoặc thay đổi #if bằng cách thêm một '!'. Bây giờ bạn về cơ bản đã chuyển đổi dịch vụ của bạn thành một ứng dụng giao diện điều khiển.

#if SERVICE_DEBUG 
      ServiceHost s = new ServiceHost(); 
      s.DebugService(); 
      Thread.Sleep(300000000); 

#else 
      ServiceBase.Run(ServicesToRun); 
#endif 

Sau khi bạn đã thiết lập và chạy, bạn có thể thực hiện bước này qua dịch vụ, cho phép bạn gỡ lỗi cả hai cùng một lúc.

Vì tò mò bạn có đang gọi đối tượng từ xa trực tiếp từ chuỗi GUI không? Nếu vậy, luồng GUI sẽ chặn cho đến khi cuộc gọi từ xa kết thúc. Điều này sẽ khóa toàn bộ GUI và làm cho nó không phản hồi. Đây không phải là giải pháp cho vấn đề, nhưng nếu trường hợp đó và chuỗi dịch vụ của bạn không trả lại, nó cũng sẽ khiến GUI bị treo.

+0

! là không thực sự tốt, vì nó sẽ chuyển đổi nó, tốt hơn tiền tố nó với một 'n'. – leppie

4

Tôi không chắc liệu điều này có giúp ích hay không, nhưng nếu bạn muốn gỡ lỗi dịch vụ khi đang chạy, bạn có thể tát mã này vào mã của bạn:

#if DEBUG 
      if (!System.Diagnostics.Debugger.IsAttached) 
       Debugger.Launch(); 
#endif 

và bạn sẽ nhận được hộp thoại yêu cầu bạn chọn trình gỡ lỗi. Đây là cách dễ dàng để đính kèm với một thể hiện đang chạy của một dịch vụ. Nếu không có gì khác, điều này sẽ cho phép bạn đột nhập vào dịch vụ của bạn khi giao diện người dùng bị treo (bằng cách nhấn nút tạm dừng trên thanh công cụ gỡ lỗi) và kiểm tra chủ đề và callstack của bạn.

+0

Tôi không có vấn đề về người hỏi, nhưng giải pháp này đã giúp tôi vô cùng. :) – rythos42

1

Một vài năm trước, tôi đã thiết kế và triển khai hệ thống kinh doanh quan trọng đã sử dụng .NET Remoting. Chúng tôi đã có một ứng dụng khách được triển khai như một GUI của Windows Forms, một máy chủ được cài đặt như một Dịch vụ Windows và một cơ sở dữ liệu SQL Server.

Tôi thiết kế để khắc phục sự cố/gỡ lỗi/phát triển, vì vậy một trong các tiêu chí thiết kế đầu tiên của tôi là tôi có thể loại bỏ toàn bộ toàn bộ .NET Remoting implementation và chạy toàn bộ hệ thống trên máy tính để bàn của mình. Vì vậy, tôi có thể tắt chức năng truy cập từ xa bằng cách thay đổi một thiết lập cấu hình boolean thành "false" = off.Sau đó tôi có thể khắc phục sự cố, gỡ lỗi, phát triển hoàn toàn mà không phải trả phí hoặc can thiệp của .NET Remoting.

Dường như điều này cũng có giá trị cho tình huống của bạn. Trên thực tế, tôi không thể tưởng tượng ra một tình huống mà trong đó đó không phải là một tính năng mong muốn, đặc biệt là vì nó rất dễ thực hiện.

Vì vậy, để thực hiện nó, cài đặt cấu hình được mỗi khách hàng và mã máy chủ sử dụng để quyết định lớp triển khai nào sẽ khởi tạo để giao tiếp với phía bên kia. Tất cả các giao tiếp xảy ra thông qua một giao diện C# tùy chỉnh có hai lớp thực hiện cụ thể ở mỗi bên: một lớp thực hiện giao tiếp bằng .NET Remoting, lớp kia đã thực hiện truyền thông như một cuộc gọi trực tiếp trong quá trình (các cuộc gọi trực tiếp).

Chỉ có một cặp lớp học (một ở mỗi bên) biết bất kỳ điều gì về .NET Remoting, vì vậy sự cách ly là tổng. Hầu hết thời gian, tất cả các nhà phát triển đã làm việc với điều khiển từ xa đã tắt, nhanh hơn và đơn giản hơn. Khi họ cần, trong một dịp hiếm hoi, họ đã bật tính năng này (chủ yếu là chỉ cho tôi hoặc khi ai đó kết nối với thử nghiệm/sản xuất để khắc phục sự cố).

Bằng cách này, tôi đã thực hiện giao diện Remoting chết đơn giản: đáp ứng công chúng thực hiện (Request)

Ngoài ra, tôi cũng sử dụng các chương trình gỡ rối tung đầu đề cập ở trên, và tôi đồng ý rằng bạn cần phải lưu tâm của tác động đến luồng GUI.

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