2016-09-20 7 views
1

У меня проблема с попыткой прочитать онлайн-файл из потока. Тот же код работает правильно, если он не находится внутри потока. Но если он находится внутри потока, приложение умирает.Как читать онлайн-файл из потока с помощью wxWidgets

Поток также работает правильно, если я не пытаюсь прочитать файл.

Следующий код работает правильно:

wxInputStream *httpStream; ///it is a global variable. 

void contadorFrame::ConnetAndRead()  
{  
    wxHTTP get; 
    get.SetHeader(_T("Content-type"), _T("text/xml; charset=utf-8")); 
    get.SetTimeout(10); 

    wxString sever, path; 
    getURLParts(TextCtrl_url->GetValue(), sever, path); 


    while (!get.Connect(sever ,80)) 
    wxSleep(5); 

    httpStream = get.GetInputStream(path); 

    if (get.GetError() == wxPROTO_NOERR) 
    { 
     wxString xml_buff; 
     wxStringOutputStream out_stream(&xml_buff); 

     httpStream->Read(out_stream); 
     std::string standarize(estandarizaXML(xml_buff.ToStdString())); 
     readXML(standarize.c_str());///read file from buffer 
    } 
    else 
    { 
     wxMessageBox(_T("Unable to connect!")); 
    } 

    wxDELETE(httpStream); 
    get.Close(); 
} 

Я знаю, что следует избегать использования функций GUI внутри потоков, и поэтому я стараюсь этот путь.

void contadorFrame::ConnetAndRead() 
{ 
    wxHTTP get; 
    get.SetHeader(_T("Content-type"), _T("text/xml; charset=utf-8")); 
    get.SetTimeout(10); 

    wxString sever, path; 
    getURLParts(TextCtrl_url->GetValue(), sever, path); 


    while (!get.Connect(sever ,80)) 
    wxSleep(5); 

    httpStream = get.GetInputStream(path); 

    if (get.GetError() == wxPROTO_NOERR) 
    { 
     PerformCalculation(); // create and run the thread 
    } 
    else 
    { 
     wxMessageBox(_T("Unable to connect!")); 
    } 

    wxDELETE(httpStream); 
    get.Close(); 
} 

void contadorFrame::PerformCalculation()// create and run the thread  
{  
    m_pThread = new MyThread(this, httpStream); 
    m_pThread->Create(); 

    if (m_pThread->Run() != wxTHREAD_NO_ERROR) 
    { 
     wxLogError("Can't create the thread!"); 
     delete m_pThread; 
     m_pThread = NULL; 
    } 
} 

Следующий код работает неправильно

void *MyThread::Entry()  
{  
    wxCommandEvent evt(wxEVT_MYTHREAD, GetId()); 

    wxString xml_buff; 
    wxStringOutputStream out_stream(&xml_buff); 
    httpStream->Read(out_stream);    //this fails 

    std::string standarize(estandarizaXML(xml_buff.ToStdString())); 
    readXML(standarize.c_str());///read file from buffer 

    wxPostEvent(m_pHandler, evt); 
    return (wxThread::ExitCode)0; // success 
} 

Любой человек может помочь решить эту проблему? Другой способ сделать то же самое? спасибо!

ответ

0

У меня есть решение. Но это не работает отлично!

http://docs.wxwidgets.org/trunk/classwx_socket_base.html

При использовании wxSocket из нескольких потоков, даже неявно (например, с использованием wxFTP или wxHTTP в другом потоке) вы должны инициализировать сокеты от основного потока, вызвав Initialize(), прежде чем создавать другие.

void contadorFrame::ConnetAndRead() 
{ 
    wxHTTP get; 
    get.Initialize(); 


    get.SetHeader(_T("Content-type"), _T("text/xml; charset=utf-8")); 
    get.SetTimeout(10); 

    wxString sever, path; 
    getURLParts(TextCtrl_url->GetValue(), sever, path); 


    while (!get.Connect(sever ,80)) 
    wxSleep(5); 

    httpStream = get.GetInputStream(path); 

    if (get.GetError() == wxPROTO_NOERR) 
    { 
     PerformCalculation(); // create and run the thread 
    } 
    else 
    { 
     wxMessageBox(_T("Unable to connect!")); 
    } 

    wxDELETE(httpStream); 
    get.Close(); 
} 

это не удается, но если я делаю (wxHTTP получить) глобальную переменную, как это, то он работает

wxHTTP get; 
void contadorFrame::ConnetAndRead() 
{ 

    get.Initialize(); 


    get.SetHeader(_T("Content-type"), _T("text/xml; charset=utf-8")); 
    get.SetTimeout(10); 

    wxString sever, path; 
    getURLParts(TextCtrl_url->GetValue(), sever, path); 


    while (!get.Connect(sever ,80)) 
    wxSleep(5); 

    httpStream = get.GetInputStream(path); 

    if (get.GetError() == wxPROTO_NOERR) 
    { 
     PerformCalculation(); // create and run the thread 
    } 
    else 
    { 
     wxMessageBox(_T("Unable to connect!")); 
    } 

    wxDELETE(httpStream); 
    get.Close(); 
} 

Сейчас проблема заключается в том, что отладчик говорит мне предупреждение как это.

../../scr/common/socket.cpp(297) утверждают «» приложение «» не удалось Init(): сокеты не могут быть инициализированы без wxApp Вы хотите, чтобы остановить программу ?

если я выбираю НЕТ, программа работает безупречно !!

Каков правильный способ инициализации сокета? То есть, где я должен поместить это (wxHTTP :: Initialize()), чтобы не получать предупреждающие сообщения от отладчика?

0

РЕШИТЬ :-)

Я сделал это

bool contadorApp::OnInit() 
{ 
    wxSocketBase::Initialize(); 

    //(*AppInitialize 
    bool wxsOK = true; 
    wxInitAllImageHandlers(); 
    if (wxsOK) 
    { 
     contadorFrame* Frame = new contadorFrame(0); 
     Frame->Show(); 
     SetTopWindow(Frame); 
    } 
    //*) 
    return wxsOK; 
} 

и это

class contadorFrame: public wxFrame 
{ 
    public: 
     wxHTTP get; 
}; 

теперь работает отлично !!

thx u guys !!

Смежные вопросы