2009-04-30 34 views
5

Tôi đang sử dụng chuỗi nền để khởi tạo công cụ qua USB. Giao diện người dùng bị treo khi tôi cố mở thiết bị. Tôi hy vọng chuỗi nền sẽ tạm dừng khi gọi Mở trên thiết bị chứ không phải là chuỗi giao diện người dùng. Tôi đang thử nghiệm điều này mà không có tương tác UI từ chủ đề nền. Tôi không biết làm thế nào để gỡ lỗi vấn đề, và nó quá rộng một câu hỏi, nhưng có lẽ ai đó đã nhìn thấy một cái gì đó như thế này trước đây. Không có gì sai với interop ActiveX như xa như tôi biết, thiết bị hoạt động chính xác. Đây là cách tiếp cận chung:Làm thế nào một chủ đề nền có thể treo chuỗi giao diện người dùng?

using System; 
using FancyVoltmeterLibrary; 

namespace SOQuestion 
{ 
    public class MeterClass 
    { 
     private FancyVoltmeter meter; 
     private Thread meterThread; 

     public MeterClass() 
     { 
      // Create instance of ActiveX/COM object. 
      meter = new FancyVoltmeter(); 

      meterThread = new Thread(UpdateMeter); 
      meterThread.Name = "Meter Thread"; 
      meterThread.Priority = ThreadPriority.Normal; 
      meterThread.IsBackground = true; 
      meterThread.Start(); 
     } 

     private void UpdateMeter() 
     { 
      while(true) 
      { 
       Thread.Sleep(1000); 
       if(!meter.IsOpen()) 
       { 
        // Meter may be powered off here. 
        // The call to Open takes about 1 second. 
        // UI hangs during the call??? 
        meter.Open(); 
       } 
       // code to read meter goes here. 
      } 
     } 
    } 
} 

Chỉnh sửa: Có lẽ không rõ ý tôi là gì. Bằng cách 'treo' tôi nên nói 'bị đóng băng trong giây lát'.

Trả lời

3

Đồng hồ có yêu cầu chạy trong STA không? Có phải cuộc gọi đến Open() thực sự đang được sắp xếp lại thành chuỗi giao diện người dùng vì lý do này không?

Bạn có thể xác minh điều này là đúng bằng cách xem chuỗi cuộc gọi của chuỗi giao diện người dùng bị treo trong trình gỡ lỗi.

+0

UI chỉ đóng băng trong một giây và tôi không biết cách ngắt trong trình gỡ lỗi trong trường hợp này. Nhưng bạn đã cho tôi một ý tưởng để đặt dòng mới 'FancyVoltmeter()' trong trình xử lý chuỗi 'UpdateMeter'. Giao diện người dùng không còn bị đóng băng nữa và điều này rất thú vị. –

0

Tôi sẽ đề nghị bạn kết thúc cuộc gọi đến meter.open() trong một phương thức riêng biệt và gọi phương thức đó từ bên trong phương thức updateMeter() bằng cách sử dụng cấu trúc Invoke() hoặc BeginInvoke() trên biểu mẫu hoặc kiểm soát cha mẹ. Làm điều này sẽ sắp xếp lại hành động trở lại luồng UI và nên thực hiện một cách duyên dáng. Tôi hi vọng cái này giúp được.

+0

Tôi vừa thử điều này và nó vẫn đóng băng cửa sổ chính trong suốt cuộc gọi Mở. Tôi đã thử MethodInvoker với điều này: var hwnd = Process.GetCurrentProcess(). MainWindowHandle; mainWnd = Control.FromHandle (hwnd); nếu (mainWnd! = Null) mainWnd.Invoke (phương pháp); –

+0

Không phải là ít nhiều sẽ đảm bảo hành vi chính xác đang cố tránh trong câu hỏi? Nếu cuộc gọi mở mất một lúc và là lực để thực thi trên chuỗi giao diện người dùng, chắc chắn giao diện người dùng sẽ không phản hồi trong thời gian đó? –

0

Cân nhắc sử dụng BackgroundWorker cho tác vụ này.

+0

Tôi đã thử BackgroundWorker trước và ứng dụng vẫn đóng băng định kỳ khi Open được gọi. Việc khởi tạo điều khiển ActiveX trong chuỗi công việc là điều duy nhất hoạt động, cho đến nay. –

2

Quá trình instantiation của FancyVoltmeter mất bao lâu? Nó có thể được rằng nó không phải là phương pháp mở gây ra đóng băng UI, nhưng tạo đối tượng COM (được thực hiện trên thread UI)?

Nếu điều đó trở thành trường hợp, việc di chuyển việc tạo đối tượng này xảy ra trên chuỗi công nhân mới, riêng biệt sẽ giải quyết vấn đề.

Chỉnh sửa: Tôi thấy bây giờ bạn đã tìm thấy điều này trong nhận xét của mình cho Michael ...

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