Đi qua những gì nhìn vào cái nhìn đầu tiên như một vấn đề MT, nhưng tôi đang cố gắng để hiểu chi tiết mô hình STA được sử dụng bởi COM +.Legacy VB6 COM + DLL gọi vào bản địa Win32 DLL - vấn đề luồng với STA?
Có hiệu quả, tôi có một thành phần COM + kế thừa, được viết bằng VB6, mà các cuộc gọi vào một bản địa (ví dụ, không phải COM) Win32 DLL được viết bằng C++.
Có một số vấn đề liên tục (và không thể tái tạo trong thử nghiệm) với nó, tôi đã thêm một số mã gỡ lỗi để tìm hiểu những gì đang diễn ra và thấy rằng khi sự cố xảy ra, tôi có thông điệp tường trình xen kẽ trong tệp - ngụ ý rằng DLL đã được gọi bởi hai chủ đề cùng một lúc.
Bây giờ ghi nhật ký đi vào một tập tin trên mỗi luồng dựa trên _getpid() và GetCurrentThreadId(), do đó, dường như khi mã trong DLL C++ được gọi, nó được gọi hai lần trên cùng một luồng cùng một lúc . Sự hiểu biết của tôi về STA cho biết điều này có thể là trường hợp như COM marshalls trường hợp cá nhân của các đối tượng vào một chuỗi treo đơn và tiếp tục thực hiện theo ý muốn.
Unfortuantly Tôi không chắc chắn nơi để đi từ đây. Tôi đang đọc rằng tôi nên gọi CoInitialiseEx() trong DllMain() để nói với COM rằng đây là một DLL STA, nhưng những nơi khác nói rằng điều này chỉ hợp lệ cho COM DLL và sẽ không có bất kỳ tác dụng trong một DLL bản địa. Lựa chọn duy nhất khác là để bọc các phần của DLL lên như là phần quan trọng để serialize truy cập (lấy bất kỳ hiệu suất hit có trên cằm).
Tôi có thể thử và làm lại DLL, nhưng không có trạng thái chia sẻ hoặc toàn cục - tất cả mọi thứ trong biến cục bộ, vì vậy trong lý thuyết, mỗi cuộc gọi sẽ có ngăn xếp riêng, nhưng tôi tự hỏi liệu mô hình STA có cơ bản không lẻ có hiệu lực về điều này và chỉ cần nhập lại vào DLL đã được nạp tại cùng một điểm vào như một cuộc gọi khác. Thật không may, tôi không biết làm thế nào để chứng minh hoặc kiểm tra lý thuyết này.
Các câu hỏi cơ bản là:
- Khi một STA COM + thành phần gọi một DLL có nguồn gốc, không có gì trong mô hình STA để ngăn chặn các hoạt động "chủ đề" bị đình chỉ và điều khiển được truyền qua một "chủ đề "ở giữa cuộc gọi DLL?
- CoInitialiseEx() có đúng cách để giải quyết vấn đề này hay không?
- Nếu không (1) hoặc (2) là giả định "tốt", điều gì đang xảy ra?
>> nó được gọi hai lần trên cùng một chuỗi cùng một lúc. << Bây giờ điều đó thật buồn cười vì nó không thể là "cùng một lúc". Có lẽ mã này là đệ quy gọi chính nó là tốt nhất. – wqw