2010-05-06 18 views
12

Tôi có một DLL không được quản lý với một hàm có thể chạy trong một thời gian dài nếu tham số đầu vào là một giá trị lớn, đôi khi đó là mong muốn nhưng không phải lúc nào.Hủy bỏ cuộc gọi không được quản lý DLL

Tôi có thể gọi hàm này bằng cách nào để tôi có thể hủy bỏ khi cần thiết?

Cho đến nay tôi đã cố gắng thực hiện cuộc gọi trong một chuỗi riêng biệt, nhưng không ngắt hoặc hủy bỏ dường như dừng quá trình, chạy ở 100% CPU cho đến khi dll được thực hiện.

Có thể chấm dứt mã dll đang chạy không?

Trả lời

23

Mã không được quản lý chỉ bị hủy bỏ nếu đó là "trạng thái chờ có thể cảnh báo". Nó sẽ không được khi nó đang cháy 100% chu kỳ CPU. P/Gọi TerminateThread sẽ làm việc, giả sử bạn có thể có được xử lý thread, mà .NET làm cho rất khó khăn. Nó sẽ không giúp đỡ anyway, bạn sẽ bị rò rỉ ngăn xếp thread. Với một megabyte, bạn sẽ nhanh chóng hết bộ nhớ ảo. Ngay cả khi đây chỉ là một nhu cầu thường xuyên, bạn vẫn phải chịu trách nhiệm để chạy vào các vấn đề lớn kể từ khi thread đã biến đổi trạng thái chương trình toàn cầu và bạn không biết làm thế nào để khôi phục lại nó.

Cách tốt nhất để hủy bỏ mã không được quản lý là chạy nó trong một quy trình riêng biệt và bắn nó vào đầu bằng Process.Kill(). Hệ điều hành sẽ dọn sạch mảnh đạn. Bạn sẽ cần phải viết một chương trình lưu trữ nhỏ cho DLL và sử dụng một trong các cơ sở interop quá trình để nói chuyện với nó. Ổ cắm, đặt tên đường ống, .NET remoting, WCF, lấy lựa chọn của bạn.

+4

+1 để đề cập đến cảnh quay đầu;) – Nate

+1

Một tùy chọn khác là thực hiện tương tự trong miền ứng dụng riêng biệt. –

+1

Không, appdomains có nghĩa là không có gì với mã không được quản lý. –

4

Từ MSDN

Nếu Abort được gọi bằng một sợi chỉ quản lý trong khi nó đang thực thi mã không được quản lý, một ThreadAbortException không được ném cho đến khi trở thread để quản lý mã.

Vì vậy, có vẻ như, hủy bỏ chuỗi được quản lý là không thể.
Thay vào đó, bạn có thể thử bắt đầu một chuỗi không được quản lý bằng Win32 APIs CreateThread(), WaitForSingleObject()TerminateThread(). Sử dụng chữ ký từ here.

Tôi đã không thử điều này bản thân mình, nhưng nó chắc chắn giới thiệu một số rủi ro, vì bạn không thể xác định tại thời điểm thực hiện bạn đang giết chết các chủ đề. Nó cũng có thể dẫn đến rò rỉ tài nguyên. MSDN liệt kê một số tác dụng phụ trên tham chiếu TerminateThread().

Nói chung, tôi khuyên bạn nên chống lại loại gián đoạn này. Có lẽ bạn có khả năng thay đổi DLL không được quản lý để cho phép xóa bỏ một cách duyên dáng.