2012-09-12 85 views
8

Ở giữa yêu cầu về manually managing CLR memory, tôi nhận ra rằng tôi biết rất ít.Mã C# không được biên dịch có biên dịch thành IL và chạy trên CLR không?

Tôi biết rằng CLR sẽ đặt một 'cookie' trên ngăn xếp khi bạn thoát khỏi ngữ cảnh được quản lý, để Bộ gom rác sẽ không lấy mẫu bộ nhớ của bạn; tuy nhiên, trong tất cả mọi thứ tôi đã đọc giả định là bạn đang gọi một số thư viện được viết bằng C.

Tôi muốn viết toàn bộ ứng dụng của mình trong C#, bên ngoài ngữ cảnh được quản lý, để quản lý dữ liệu ở mức thấp cấp độ. Sau đó, tôi muốn truy cập lớp này từ một lớp được quản lý.

Trong trường hợp này, mã C# không được quản lý của tôi sẽ biên dịch sang IL và được chạy trên CLR? Cái này hoạt động ra sao?

+0

Bạn đề cập đến việc viết mã không được quản lý trong C#. Tôi giả sử bạn có nghĩa là điều này khác với * gọi * mã không được quản lý * từ * C#. Nếu vậy, tôi muốn xem một ví dụ về ý của bạn. –

+0

Dựa trên câu trả lời của oleksii, những gì tôi đang tìm kiếm đơn giản là không tồn tại. Vì vậy, tôi không thực sự có thể cho bạn thấy một ví dụ. – kd8azz

Trả lời

12

Tôi cho rằng điều này liên quan đến cùng một dự án cơ sở dữ liệu C# mà bạn đã đề cập trong câu hỏi.

Đó là về mặt kỹ thuật có thể để triển khai toàn bộ các lớp ghi trong C/C++ hoặc bất kỳ ngôn ngữ nào khác. Và nó là về mặt kỹ thuật có thể để có mọi thứ khác trong C#. Tôi hiện đang làm việc trên một ứng dụng sử dụng mã không được quản lý cho một số công cụ cấp thấp hiệu suất cao và C# cho logic nghiệp vụ và quản lý cấp cao hơn.

Tuy nhiên, mức độ phức tạp của tác vụ sẽ không được đánh giá thấp. Cách điển hình để thực hiện việc này là thiết kế hợp đồng mà cả hai bên đều có thể hiểu được. Hợp đồng sẽ được tiếp xúc với ngôn ngữ được quản lý và ngôn ngữ được quản lý sẽ kích hoạt các cuộc gọi đến ứng dụng gốc. Nếu bạn đã từng thử gọi phương thức C++ từ C#, bạn sẽ nhận được ý tưởng ... Thêm vào đó, mọi cuộc gọi tới mã không được quản lý đều có hiệu suất khá cao, điều này có thể làm giảm toàn bộ ý tưởng về hiệu suất ở mức thấp.

Nếu bạn thực sự quan tâm đến cơ sở dữ liệu quan hệ hiệu suất cao, hãy sử dụng một ngôn ngữ cấp thấp.

Nếu bạn muốn có một thực hiện ngây thơ, nhưng hoàn toàn làm việc của một cơ sở dữ liệu, chỉ cần sử dụng C#. Đừng trộn lẫn hai ngôn ngữ này trừ khi bạn hoàn toàn hiểu được sự phức tạp. Xem Raven DB - một cơ sở dữ liệu NoSQL dựa trên tài liệu được xây dựng hoàn toàn chỉ trong C#.

Mã C# không được quản lý của tôi có biên dịch sang IL và chạy trên CLR không?

Không, không có điều gì như không được quản lý C#. Mã C# sẽ luôn được biên dịch thành mã IL và được thực thi bởi CLR. Đó là trường hợp mã được quản lý gọi là mã không được quản lý. Không được quản lý mã có thể được thực hiện trong một số ngôn ngữ C/C++/Assembly vv, nhưng CLR sẽ không có ý tưởng về những gì đang xảy ra trong mã đó.

Cập nhật từ nhận xét. Có một công cụ (ngen.exe) có thể biên dịch C# trực tiếp thành mã cụ thể của kiến ​​trúc gốc. Công cụ này được thiết kế để cải thiện hiệu suất của ứng dụng được quản lý bằng cách loại bỏ giai đoạn biên dịch JIT và đưa mã gốc trực tiếp vào hình ảnh hoặc thư viện thực thi. Mã này, tuy nhiên, vẫn được "quản lý" bởi máy chủ CLR - cấp phát bộ nhớ và quản lý, quản lý luồng, miền ứng dụng, xử lý ngoại lệ, bảo mật và tất cả các khía cạnh khác vẫn được kiểm soát bởi CLR. Vì vậy, mặc dù C# về mặt kỹ thuật có thể được biên dịch thành mã gốc, nhưng mã này không hoạt động như một hình ảnh gốc độc lập.

Tính năng này hoạt động như thế nào?

Managed đang tương thích với mã không được quản lý. Có một số cách để thực hiện việc này:

  • Thông qua mã qua .Net Interop. Điều này tương đối nhanh nhưng trông hơi xấu trong mã (cộng với khó duy trì/thử nghiệm) (good article with C#/C/Assembly samples)
  • Cách tiếp cận chậm hơn nhiều, nhưng mở rộng hơn với các ngôn ngữ khác: web wervices (SOAP, WS, REST và công ty), xếp hàng (như MSMQ, NServiceBus và những người khác), cũng có thể (có thể) liên lạc giữa các quá trình. Vì vậy, quy trình không được quản lý nằm ở một đầu và một ứng dụng được quản lý nằm trên một ứng dụng khác.
+1

+1 để có câu trả lời rõ ràng về câu hỏi 'không được quản lý C#' –

+0

@ oleksii- Có một ngoại lệ đối với mã _C# nhận xét của bạn sẽ luôn được biên dịch thành mã IL_. Nếu sử dụng triển khai thực hiện .Net của Microsoft, có một công cụ có tên là ngen.exe biên dịch mã IL thành mã gốc, tránh chi phí của quá trình biên dịch mã nguồn gốc trong thời gian gần đây, lần đầu tiên xuất hiện một phương thức hoặc hàm được gọi là. Tuy nhiên, điều này có thể phản tác dụng khi ngen.exe phải nhắm mục tiêu một kiến ​​trúc nhất định trước và trình biên dịch JIT có thể sử dụng các tối ưu hóa có sẵn cho nền tảng thực sự chạy mã. Chúc mừng! –

+0

@GerardSexton, xin lỗi nhận xét ban đầu của tôi đã được gửi đến bạn thay vì oleksii –

1

Tôi biết đây là câu hỏi C#, nhưng nếu bạn cảm thấy thoải mái với C++, C++/CLI có thể là một lựa chọn đáng xem xét.

Nó cho phép bạn chọn lọc biên dịch các phần của mã C++ thành ngữ cảnh được quản lý hoặc không được quản lý - Tuy nhiên, hãy lưu ý rằng mã tương tác với các kiểu CLR PHẢI chạy trong ngữ cảnh được quản lý.

Tôi không biết chi phí thời gian chạy chuyển từ ngữ cảnh được quản lý sang ngữ cảnh không được quản lý và ngược lại từ bên trong mã C++, nhưng tôi cho rằng nó phải giống với chi phí gọi phương thức gốc thông qua .net Interop từ C#, như @oleksii đã chỉ ra, là tốn kém. Theo kinh nghiệm của tôi, điều này đã thực sự được đền đáp nếu bạn cần tương tác thường xuyên với các thư viện C hoặc C++ bản địa - IMHO dễ dàng gọi chúng từ bên trong một dự án C++/CLI hơn là viết các giao tiếp Interop yêu cầu trong C#.

Xem thông tin này question để biết thông tin về cách thực hiện.

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