2009-07-03 14 views
7

Tôi đang chạy một dịch vụ windows đa luồng cần gọi một dll VB6. Không có tài liệu về dll VB6 này và hệ thống kế thừa này hỗ trợ một quy trình kinh doanh rất quan trọng.Làm thế nào chúng ta có thể làm việc với VB6 dll được gọi là từ một ứng dụng đa dịch vụ C# windows?

Lúc đầu (chủ đề 1º), dll này hoạt động tốt. Khi các chủ đề khác cần truy cập, nó bắt đầu cung cấp kết quả sai.

Tôi đọc một chàng trai nói:.

"Chỉ cần cẩn thận một điều rằng nếu bạn đang sử dụng VB6 mô hình luồng của bạn sẽ phải thay đổi để hỗ trợ các căn hộ nếu bạn đang chạy một dịch vụ đa luồng VB. chỉ hỗ trợ nhiều căn hộ đơn luồng, nhưng .NET chạy hoàn toàn miễn phí luồng thông thường. Chủ đề gọi vào VB6 DLL cần phải tương thích với DLL. "

Một anh chàng khác trong nhóm đã cho tôi ý tưởng đưa ddl này vào một miền ứng dụng riêng biệt. Nhưng tôi không chắc chắn.

Làm thế nào chúng ta có thể làm việc với VB6 dll được gọi là từ một ứng dụng dịch vụ đa cửa sổ C#?

+0

Để cung cấp cho bạn câu trả lời dứt khoát, chúng tôi cần thêm thông tin: nó có chạy dưới COM + hay không, trong trường hợp cũ thực hiện trong hoặc ngoài quá trình? Làm thế nào để bạn cài đặt nó trong một hệ thống: thông qua regsvr32 hoặc phương tiện khác? –

+0

Cảm ơn các bạn, tôi đã tìm ra vấn đề là gì. Dll này không phải là nghĩa vụ phải làm việc với bất cứ điều gì khác hơn VB 6. Nó có một lỗi bên trong. Nó không chấp nhận cài đặt khu vực tiếng Anh trên máy chủ, chúng tôi đã phải thay đổi ngôn ngữ Bồ Đào Nha; ngôn ngữ của khách hàng. Cho đến nay tôi đang sử dụng mẫu đơn và mẫu proxy để làm việc với thành phần kế thừa này và bây giờ nó hoạt động tốt. –

Trả lời

2

Khi chủ đề đến, bạn có lưu các đối tượng và sử dụng lại chúng sau này không? Nếu bạn có thể, hãy tạo các đối tượng mới cho mỗi luồng. Chúng tôi có một tình huống như thế này với dll lớp dữ liệu mà chúng tôi sử dụng. Nếu bạn tạo một kết nối trên một luồng, nó không thể được sử dụng từ một luồng khác. Nếu bạn tạo một kết nối mới trên mỗi luồng, nó hoạt động tốt.

Nếu tạo chậm đối tượng của bạn, hãy nhìn vào lớp ThreadPool và thuộc tính ThreadStatic. Threadpools tái chế cùng một tập hợp các chủ đề hơn và hơn để làm việc, và ThreadStatic cho phép bạn tạo một đối tượng tồn tại chỉ cho một luồng. ví dụ

[ThreadStatic] 
public static LegacyComObject myObject; 

Là một yêu cầu đến, biến nó thành một công việc và xếp hàng nó trong hồ bơi thread của bạn. Khi công việc bắt đầu, kiểm tra xem đối tượng tĩnh được khởi tạo hay chưa;

void DoWork() 
{ 
    if (myObject == null) 
    { 
     // slow intialisation process 
     myObject = New ... 
    } 

    // now do the work against myObject 
    myObject.DoGreatStuff(); 
} 
0

This article on multithreading Visual Basic 6 DLL's cung cấp một số thông tin chi tiết. Nó nói:

Để thực hiện ActiveX DLL dự án đa luồng, chọn mong muốn tùy chọn luồng trên tab General của Dự án hộp thoại Properties.

This article nói có ba mô hình tốt để lựa chọn:

One thread of execution 
Thread pool with round-robin thread assignment 
Every externally created object is on its own thread 

tôi cho rằng mặc định là one thread of execution, và đó là một trong hai tùy chọn khác cần phải được lựa chọn.

0

Bạn có thể muốn xem xét điều này: linky

Và đây là một đoạn mà tôi chú ý:

đối tượng VB6 COM là những đối tượng STA, có nghĩa là họ phải chạy trên một STA chủ đề. Bạn đã tạo hai cá thể của đối tượng từ hai chuỗi MTA, nhưng đối tượng sẽ chạy trên một chuỗi (COM (OLE) được tạo) STA và truy cập từ hai chuỗi MTA sẽ được sắp xếp và đồng bộ hóa. Vì vậy, những gì bạn nên làm là, khởi tạo các chủ đề như STA để mỗi đối tượng chạy trên thread STA của riêng mình mà không marshaling và bạn sẽ được sử dụng tốt.

Dù sao, các đối tượng COM kiểu VB luôn là STA. Bây giờ để ngăn chặn căn hộ marshaling và thread chuyển đổi bạn cần phải tạo ra trường hợp trong STA căn hộ khởi tạo. Cũng lưu ý rằng khi bạn đặt thuộc tính [MTAThread] trên Main, bạn khởi tạo chủ đề chính là MTA, khi bạn tạo trường hợp đối tượng STA từ chủ đề MTA COM sẽ tạo một luồng riêng biệt (không được quản lý) và khởi tạo nó là STA (điều này được gọi là mặc định STA), tất cả các cuộc gọi đến các đối tượng STA từ các chủ đề MTA sẽ được sắp xếp (và có thể chuyển đổi luồng), trong một số trường hợp Idispatch gọi sẽ không thành công do lỗi marshaling IP. Vì vậy, tư vấn chỉ sử dụng các đối tượng STA (và do đó VB6) từ các căn hộ tương thích.

1

Bạn nói

Tôi đang chạy một cửa sổ đa luồng dịch vụ mà cần phải gọi một dll VB6. Không có tài liệu nào về số này dll VB6 và hệ thống kế thừa này hỗ trợ quy trình kinh doanh rất quan trọng .

và đồng thời bạn nói

Tại lần đầu tiên (1º thread), dll này hoạt động tốt. Vì các chủ đề khác cần truy cập , nó bắt đầu cung cấp sai kết quả .

Tôi rất chắc chắn rằng Quản lý nhận thức được sự cố bạn thấy vì mã hỗ trợ quy trình nghiệp vụ quan trọng cũ và không có giấy tờ và đang được sử dụng theo cách không bao giờ được sử dụng và chưa bao giờ được thử nghiệm để sử dụng. Tôi đặt cược nó cũng không bao giờ được thử nghiệm để được sử dụng từ. NET trước, có nó?

Đây là đề xuất của tôi và điều này tương tự với đề xuất mà tôi đã thực hiện:

VB6 DLL dự kiến ​​sẽ được gọi trên một chuỗi duy nhất. Đừng thất vọng! Khi dịch vụ của bạn bắt đầu, hãy bắt đầu một chuỗi loại thích hợp (Tôi không thể nói, vì tôi đã cố tình quên tất cả các công cụ STA/MTA đó). Xếp hàng các yêu cầu đến chuỗi đó để truy cập vào DLL VB6. Có tất cả các truy cập như vậy đi qua các chủ đề duy nhất.

Bằng cách đó, theo như VB6 DLL có liên quan, nó chạy chính xác như nó đã được thử nghiệm để chạy.


BTW, điều này hơi khác so với những gì tôi đã triển khai. Tôi đã có một dịch vụ web, không phải là một Dịch vụ Windows. Tôi đã có một DLL C, không VB6, và nó không phải là COM. Tôi chỉ cần refactored tất cả các truy cập vào điều vào một lớp duy nhất, sau đó đặt báo cáo khóa xung quanh mỗi phương pháp công cộng.

+0

Tôi không thể đồng ý với John nhiều hơn. Kể từ khi VB6 DLL có hiệu quả một hộp đen cho bạn, đi với những gì được đảm bảo là đúng sự thật. Tốt nhất, DLL sẽ hỗ trợ một mô hình luồng đơn luồng (STA). Xem liên kết này trên MSDN để xem xét khi gọi một đối tượng COM STA: http://msdn.microsoft.com/en-us/library/ms680112(VS.85).aspx. Đối với tối đa bang cho buck, bạn có thể muốn chỉ đơn giản là tận dụng một bộ chuyển đổi hoặc singleton để điều chỉnh truy cập đối tượng đến một thread tại một thời điểm (như John đề nghị). Hãy chắc chắn để xem COM interop của bạn và marshalling từ. NET, quá. –

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