2012-03-09 32 views
5

Tôi có một máy chủ COM gốc (Delphi) được quảng cáo là STA (Căn hộ Mô hình Threaded).Có bất kỳ lý do nào tại sao việc thiết lập một máy khách .NET được quản lý để sử dụng các luồng STA sẽ gây ra các vấn đề với các ngoại lệ trong một máy chủ COM gốc?

Nó chứa một vài thuật toán ném ngoại lệ tràn trong một số trường hợp. Những trường hợp ngoại lệ được xử lý trong mã, và tất cả mọi thứ hoạt động như nó nên nếu tôi truy cập vào máy chủ COM từ một khách hàng trên các chủ đề chính.

Nếu khách hàng là người bản xứ (Delphi), tôi có thể truy cập máy chủ từ nhiều chủ đề miễn là tôi tuân theo quy tắc mà đối tượng được tạo trên một chuỗi tạo tất cả các cuộc gọi phương thức từ cùng một chuỗi đó. Tuy nhiên nếu khách hàng là một khách hàng được quản lý (Vb.NET và C# thử nghiệm), nếu tôi đặt ApartmentState của các chủ đề khách hàng để MTA, tất cả mọi thứ hoạt động tốt, nhưng tôi nhận được một hit hiệu suất. Điều này tôi mong đợi, như tôi đoán COM phải làm một số pokemon jiggery (tức là marshaling) để đảm bảo mọi người đều hạnh phúc.

Tuy nhiên nếu tôi thay đổi ApartmentState thành STA, và do đó đảm bảo kết nối trực tiếp giữa máy khách và máy chủ, máy khách sẽ gặp lỗi do lỗi, thường là System.stackoverflowexception trong CustomMarshallers.dll.

Nếu tôi loại bỏ các con số gây ra các lỗi tràn này thì tôi không gặp vấn đề gì.

Tôi có thể làm tròn điều này bằng cách tinh chỉnh các thuật toán để không phụ thuộc vào ngoại lệ (có lẽ chúng phải được viết ở nơi đầu tiên), nhưng tôi muốn hiểu lý do đằng sau những gì đang xảy ra.

+0

Mã của bạn phải an toàn trong chuỗi STA. –

+0

Mã là chủ đề an toàn. Tất cả các dữ liệu cá thể là an toàn vì nó được đảm bảo được gọi từ một luồng đơn. Tất cả dữ liệu toàn cầu đã được bảo vệ. – Steve

+0

Không tầm thường nhưng chạy máy chủ COM trong trình gỡ lỗi có thể giúp –

Trả lời

0

Có một số lượng phỏng đoán liên quan đến câu trả lời này vì bạn không trích dẫn nguyên văn lỗi và không đề cập đến giá trị HRESULT.

Có một khả năng lý thuyết rằng không gian ngăn xếp sẵn có khác nhau giữa các trường hợp STA và MTA sẽ tạo sự khác biệt cho một ngăn xếp ngăn xếp của một ứng dụng Delphi. Nhưng khả năng sau đây có nhiều khả năng hơn.

StackOverflowException có thể do chính phía Delphi (giả sử thông báo lỗi gọi là "không được giải quyết"). Xem xét kỹ hơn tất cả các cơ chế xử lý lỗi ở phía Delphi và xem xét bất kỳ cơ chế nào có thể dẫn đến đệ quy cụ thể về lỗi. Ví dụ, việc thực thi mã trên một sự kiện cụ thể có thể chứa một khối được bảo vệ, trong đó điều khoản catch thực hiện điều gì đó kích hoạt cùng một sự kiện.

Tôi cho rằng sự khác biệt mà bạn thấy với STA so với MTA sẽ phần nào thoát ra nếu bạn xóa PreserveSigAttribute khỏi mã máy khách, để ngoại lệ tràn ngăn xếp sẽ ngừng được dịch sang HRESULT mà khách hàng của bạn có lẽ bỏ qua ngay bây giờ . (Nếu bạn sử dụng tlbimp.exe, thuộc tính này đã được chỉ định ngầm định. Điều này có nghĩa là bạn muốn xử lý ngoại lệ theo cách COM là giá trị trả lại, không phải là cách .NET.)

+0

Tất cả các điểm hợp lệ không nghi ngờ gì, nhưng tại sao khách hàng gốc xử lý vấn đề này mà không có vấn đề gì. Tôi có một dòng cụ thể trong một trong các thuật toán của tôi: – Steve

+0

: nếu [icol, icol] = 0 thì tăng EMatrixError.Create ('Lỗi Ma trận'); Tôi đang cố gắng để xử lý lỗi này, nhưng như ngoại lệ unravels, tôi nhận được lỗi. Vì vậy, có, lỗi trong mã Delphi, nhưng một cái gì đó trong.NET khách hàng dường như gây ra vấn đề – Steve

+0

@Steve - lại "khách hàng tai nạn với lỗi lỗi", bạn có thể sao chép và dán tin nhắn hoặc stacktrace mà bạn nhìn thấy? Bạn đã thử in ra HRESULT từ trình khách Delphi (không được quản lý), mà khách hàng có thể bỏ qua ngay bây giờ? Nếu câu trả lời của tôi là đúng, thì HRESULT sẽ là một mã lỗi, và 'PreserveSigAttribute' sẽ là sự khác biệt duy nhất giữa hai máy khách. –