Makale numarası: 196026 - Son Gözden Geçirme: 22 Mayıs 2003 Perşembe - Gözden geçirme: 4.0

SORUN: Olayı, ikinci bir iş parçacığı tetikleme BAşLATMA veya GPF nedenleri

Sistem İpucuBu makale, kullandığınızdan farklı bir işletim sistemine yöneliktir. Sizinle ilgili olmayabilecek makale içeriği devre dışı bırakıldı.

Bu Sayfada

Hepsini aç | Hepsini kapa

Belirtiler

Visual Basic'te, ana iş parçacığı dışında başka bir iş parçacığından ActiveX bileşeni tarafından harekete olay bazen bir geçersiz sayfa hatası (BAşLATMA) veya (GPF) genel koruma hatasına neden olur. Genellikle Visual Basic ıDE'DE bağdaştırıcımla görünüyor ancak bağımsız EXE çalıştırıldığında başarısız oluyor.

Neden

Visual Basic bir bir apartman iş parçacığı modelini kullanır. Siteler-iş parçacığı işlev çağrıları sıraya gerekir. Visual Basic sıralanırken olmadan bir Visual Basic projesi tarafından oluşturulan bir ana iş parçacığı dışında başka bir iş parçacığından doğrudan harekete olayları desteklemiyor.

Çözüm

Yöntem 1

Marshall olay firing kodu:
  1. Coınitialize/CoUnInitialize çağrısı gerekiyor spun iş parçacığı.
  2. Geri üzerinde iş parçacığının ça?r?lan havuzu arabirimi üzerinden CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream ile bir iş parçacığı için sıraya gerekir.

Yöntem 2

Ikincil bir iş parçacığından olay tetikleme, yerine geri ana iş parçacığına ileti postalama ve olayı vardır. Bu makalenin sonraki bölümlerinde, bu yöntemi örneği verilmiştir.

Durum

Bu davranış tasarım yüzündendir.

Daha fazla bilgi

Davranışı yeniden oluşturma adımları

Aşağıdaki örnekte, ilk ATL projesinde, bir Visual Basic 6. 0'ın proje oluşturur. Sonra bu birincil iş parçacığı, bir olayı harekete ikincil bir iş parçacığının isteği için uygun bir şekilde göstermek için kullanır.

Visual C++ ile bir ATL proje oluşturmak için gereken adımları

  1. Bir yeni ATL COM AppWizard MyAtlDll adlı proje oluşturmak ve varsayılan ayarları saklamak.
  2. Sınıf görünümünde proje adını sağ tıklatın ve ATL nesne seçin. Basit bir nesne görüntülenen iletişim kutusunda seçin ve ileri'yi tıklatın. "Içinde MyAtl" C++ kısa adı olarak yazın. Öznitelik sekmesini tıklatın ve bağlantı noktaları Destek'i seçin. Tamam'ı tıklatın ve yeni ATL nesnesi olarak eklenir.
  3. Sınıf görünümündeki IMyAtl sağ tıklatın ve Ekle yöntemi. "InitTask", "[,] uzun numarası" ve yöntem adı metin kutusuna parametreleri</a1> metin kutusuna yazın. Tamam'ı tıklatın.
  4. Sınıf görünümündeki _IMyAtlEvents sağ tıklatıp Ekle yöntemi. Dönüş türü açılan kutuda "void" seçin. "TaskFinished", "[,] uzun sonucu" ve yöntem adı metin kutusuna parametreleri</a1> metin kutusuna yazın. Tamam'ı tıklatın.
  5. Sınıf görünümündeki CMyAtl'ı sağ tıklatın ve sonra Ekle üye değişkeni seçin. "Uzun" değişken tipi, metin kutusunu ve "m_number" <a0>değişken adı</a0> metin kutusuna yazın.
  6. Adım 10'için gerekli tür kitaplığı oluşturmak için bir proje oluşturun.
  7. Sınıf görünümündeki genişletin ve CMyAtl IMyAtl InitTask->->'ı çift tıklatın. Aşağıdaki gibi görünmesini sağlamak için InitTask işlevini düzenleyin:
          STDMETHODIMP CMyAtl::InitTask(long number)
          {
             HANDLE hThrd;
             DWORD tid;
    
             m_number = number;
             if((hThrd = CreateThread(
                     0,
                     0,
                     (LPTHREAD_START_ROUTINE)justDoIt,
                     (void *)this,
                     0,
                     &tid)) == NULL)
             {
                //error handling here
             }
             CloseHandle(hThrd);
             return S_OK;
          }
    
    					
  8. Aşağıdaki kodu MyAtl.cpp dosyasına ekleyin:
          DWORD WINAPI justDoIt(LPVOID lpParameter)
          {
             CMyAtl *myAtl = (CMyAtl*)lpParameter;
    
             long result;
             for (int i = 1; i <= myAtl->m_number; ++i)
                result = i * 2;
    
             myAtl->Fire_TaskFinished(result);
    
             return 0;
          }
    
    					
  9. Satırı sağ üstünde aşağıdaki kodu ekleyin "#endif //__MYATL_H_" MyAtl.h dosyasındaki:
          DWORD WINAPI justDoIt(LPVOID lpParameter);
    
    					
  10. Sınıf görünümündeki CMyAtl'ı sağ tıklatın ve bağlantı noktası gerçekleştir'i seçin. _IMyAt olayları görüntülenen iletişim kutusunda seçin. Tamam'ı tıklatın.
  11. ATL Projeyi derleyin ve denetimi otomatik olarak kaydedilir.

Visual Basic 6.0 projeyi oluşturmak için adımları

  1. Yeni bir standart exe DOSYASı) projesi oluşturun. Varsayılan olarak, Form1 oluşturulur.
  2. Başvurular Proje menüsünde seçin seçin "MyAtlDll 1.0 tür kitaplığı," Tamam'ı tıklatın.
  3. Forma bir KomutDüğmesi ekleyin ve varsayılan adı korunarak (command1).
  4. Form1 <a1>Kod</a1> penceresine aşağıdaki kodu ekleyin:
          Option Explicit
          Private WithEvents vbATL As MYATLDLLLib.MyAtl
    
          Private Sub Command1_Click()
             vbATL.InitTask 11111
          End Sub
    
          Private Sub Form_Load()
             Set vbATL = New MYATLDLLLib.MyAtl
          End Sub
    
          Private Sub vbATL_TaskFinished(ByVal result As Long)
             MsgBox result
          End Sub
    
    					
  5. Proje çalıştırmak için F5 tuşuna basın. Command1'ı tıklatın ve bir ileti kutusu içinde 22222 alırsınız.
  6. IDE dışında EXE bir EXE olması ve bir proje oluşturun. KomutDüğmesi tıklattığınızda bir hata iletisi alırsınız.

    Not bazen işe yarayabilir, ancak tutarlı bir şekilde çalışmaz. Belirli bu örnekte sorunu gidermek için <a0></a0>, CWindowImpl the CMyAtl türetme yapıp yapmayacağınızı ve bir ileti eşlemesi eklemek gerekir. Pencere gizli olmasına dikkat edin. Şimdi, ikincil iş parçacığının bir olaydan tetikleme yerine nakledebilir ana iş parçacığına bir ileti ve ileti işleyicisindeki olayı.

SORUNU ÇÖZÜMLEME ADIMLARI

  1. Yukarıdaki adımlarda oluşturduğunuz ATL projesini kullanarak, aşağıdaki satırı ekleyin:
          #include <atlwin.h>
    
    						
    satırdan:
          #define _MYATL_H
    
    						
    MyAtl.h dosyasındaki.
  2. Satır Ekle:
          #define WM_TASK_FINISH  (WM_USER + 101)
    
    						
    önce satır:
          class ATL_NO_VTABLE CMyAtl :
    
    						
    MyAtl.h dosyasındaki.
  3. CWindowImpl <a0></a0> CMyAtl üst sınıflarını birini eklediğinizde aşağıdaki satırı ekleyin:
          public CWindowImpl<CMyAtl>,
    
    						
    satırdan hemen:
          class ATL_NO_VTABLE CMyAtl :
    
    						
    MyAtl.h dosyasındaki.
  4. MyAtl.h dosya CMyAtl tanım bölümüne aşağıdaki kodu ekleyin:
          public:
             DECLARE_WND_CLASS("MyAtl")
    
             BEGIN_MSG_MAP(CMyAtl)
                MESSAGE_HANDLER(WM_TASK_FINISH, OnTaskFinished)
             END_MSG_MAP()
          public:
             LRESULT OnTaskFinished(UINT uMsg, WPARAM wParam,
                            LPARAM lParam, BOOL& bHandled)
             {
                Fire_TaskFinished((long)wParam);
                return 0;
             }
    
            HRESULT FinalConstruct()
            {
               RECT rect;
               rect.left=0;
               rect.right=100;
               rect.top=0;
               rect.bottom=100;
    
               HWND hwnd = Create( NULL, rect, "MyAtlWindow", WS_POPUP);
    
               if (hwnd)
                   return S_OK;
               else
                   return HRESULT_FROM_WIN32(GetLastError());
            }
    
            void FinalRelease()
            {
               if (m_hWnd != NULL)
                   DestroyWindow();
            }
    
    						
  5. Aşağıdaki satırı değiştirin:
          myAtl->Fire_TaskFinished(result);
    
    						
          DWORD WINAPI justDoIt(LPVOID lpParameter)
    
    						
    olmasını MyAtl.cpp, dosyadaki:
          myAtl->PostMessage(WM_TASK_FINISH,result,0);
    
    						
  6. ATL projeyi yeniden oluşturun.
  7. Visual Basic projesinin, IDE ve bir EXE olarak çalıştırın. Olay geçirilir yalnızca her iki durumda da ince unutmayın.

Referanslar

Ikinci bir iş parçacığından olay tetikleme ve PostMessage yöntem hakkında ek bilgi için Microsoft Knowledge Base'deki makaleleri görüntülemek üzere aşağıdaki makale numaralarını tıklatın:
157437  (http://support.microsoft.com/kb/157437/EN-US/ ) FILE: İkinci bir iş parçacığı Fireev.exe geçirilir olayları
280512  (http://support.microsoft.com/kb/280512/EN-US/ ) Örnek: COM arasında tetikleme ATL olay ATLCPImplMT saklar.

Bu makaledeki bilginin uygulandığı durum:
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
Anahtar Kelimeler: 
kbmt kbactivexevents kbcode kbprb kbthread KB196026 KbMttr
Otomatik TercümeOtomatik Tercüme
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:196026  (http://support.microsoft.com/kb/196026/en-us/ )