Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Копирование файла в потоке.

335
18 апреля 2006 года
enola
379 / / 25.01.2005
Доброе утро!
Задумал я в потоке файл копировать, сделал, как в книжках пишут, а у меня при запуске потока прога виснет, но поток выполняется:
Код:
//---------------------------------------------------------------------------

__fastcall TFileThread::TFileThread(bool CreateSuspended)
    : TThread(CreateSuspended)
{
    FreeOnTerminate = True;
}
//---------------------------------------------------------------------------

void __fastcall TFileThread::Execute()
{
    // Объявление переменных
    AnsiString InFilePath, OutFilePath;
    const size_t BufferSize = 64;
    size_t Readed;
    char DataBuffer[BufferSize];
    long FileSize, SymCount = 0;

    // Входной / выходной файл
    InFilePath = "\\\\abc-01\\t\1.txt";
    OutFilePath = "C:\\1.txt";

    // Входной / выходной файл
    ifstream In(InFilePath.c_str(), ios::in | ios::binary);
    ofstream Out(OutFilePath.c_str(), ios::out | ios::binary);

    // Проверка на доступность к файлам
    if(!In || !Out)
        return;

    // Определение размера файла
    In.seekg(0, ios::end);
    FileSize = In.tellg();
    In.seekg(0, ios::beg);

    // Сохранение файла из in в out
    while(In)
    {
        // Считывание данных в буфер
        In.read(DataBuffer, BufferSize);
        Readed = In.gcount();
        if(Readed > 0)
            Out.write(DataBuffer, Readed);

        // Подсчет кол-ва считанных символов
        SymCount += Readed;

        // Изменение позиции прогрессбара
        Pos = SymCount * 100 / FileSize;
        Synchronize(UpdateProgress);
    }

    // Закрытие файлов
    In.close();
    Out.close();
}
//---------------------------------------------------------------------------

void __fastcall TFileThread::UpdateProgress()
{
    Form1->ProgressBar->Position = Pos;
}
//---------------------------------------------------------------------------


а вот так я его запускаю:
 
Код:
File = new TFileThread(true);
    File->Resume();


скажите чего не дочитал я?
585
18 апреля 2006 года
honeybeer
297 / / 06.09.2004
Немного не в тему, но все же. Почему нельзя скопировать так:
 
Код:
ifstream ifile("...");
    ofstream ofile("...");
    ofile << ifile;
    ifile.close();
    ofile.close();
335
18 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by honeybeer
Немного не в тему, но все же. Почему нельзя скопировать так:
 
Код:
ifstream ifile("...");
    ofstream ofile("...");
    ofile << ifile;
    ifile.close();
    ofile.close();



Вот несколько весомых доводов:
1. Если копировать твоим способом по локальной сети (а у меня именно так), то прога подвисает, до окончания процесса копирования.
2. Если считывать построчно, а потом сохранять (тут еще один момент - индикатор копирования для пользователя), а в перерывах ставить ProcessMessage (что не очень красиво), то это не совсем правильно.

По-моему потоки и предназначены для длительных, законченных операций, или я не прав?

А как мою задачку решить?

246
18 апреля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by enola
Доброе утро!
Задумал я в потоке файл копировать, сделал, как в книжках пишут, а у меня при запуске потока прога виснет, но поток выполняется:
...
скажите чего не дочитал я?


не силен я в STL, но эта проверка окночания цикла смущает

 
Код:
while(In)
    {

тем более, что дальше по тексту идет обращение к
 
Код:
// Закрытие файлов
    In.close();
246
18 апреля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by GIZMO
не силен я в STL, но эта проверка окночания цикла смущает
 
Код:
while(In)
    {


Ну ясно дело д.б. while(!In->eof())
2. Не выставлен диапазон у ProgressBar-a
3. Нахер тебе этот STL сдался используй TFileStraem, API (не люблю я ее)

335
18 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by GIZMO
не силен я в STL, но эта проверка окночания цикла смущает
 
Код:
while(In)
    {

тем более, что дальше по тексту идет обращение к
 
Код:
// Закрытие файлов
    In.close();



В STL я тоже не шибко, но по-моему все нормально, опирует проверял :)

Но здесь дело не в том как копируется, а где (или даже в чем) копируется. Мне кажется вся проблема в синхронизации потока, но что сделать ума не приложу?

вот если убрать:

 
Код:
Synchronize(UpdateProgress);


и вставить:
 
Код:
UpdateProgress();


то все работает как надо, но это не правильно, т.к. поток обращается к форме. Пробовал сделать приоритет низким не помогает.
Что сделать?

P.S. Млин у меня еще поток с часами тоже висит :) во дела. Никогда с потоками дело не имел.
1
18 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by GIZMO
не силен я в STL, но эта проверка окночания цикла смущает
 
Код:
while(In)
    {

тем более, что дальше по тексту идет обращение к
 
Код:
// Закрытие файлов
    In.close();


Форма проверки завершения потока вполне идиоматична. Здесь используется объект файлового потока, а не указатель на него. И STL тут каким боком? :)
Попытайся для начала увеличить буфер - 64 байта - слишком мало - хотя бы 512. Возможно, с этим тормоза и связаны. Кроме того, синхронизируй данные напрямую.

1
18 апреля 2006 года
kot_
7.3K / / 20.01.2000
И второе - обрати внимание - файловые потоки - это буферизованное чтение - т.е. файл помещается вначале в буфер при открытии, а ты работаешь уже с ним. Если нужно можно использовать функции прямого доступа ::read(...)&&::write(...)
8.7K
18 апреля 2006 года
Rubicon
55 / / 28.10.2005
Выдержка из хелпа:

Synchronize waits for the main VCL thread to enter the message loop and then executes the passed method
//-----------------------------------------
TApplication::ProcessMessages

Interrupts the execution of an application so that Windows can process the message queue.

Вдумайся в эти строки.
Цитата:
Мне кажется вся проблема в синхронизации потока

--- вот именно... Дай бедняге отдохнуть. Твой поток только и делает, что крутится и крутится, поэтому занимает бОльшую часть процессорного времени, поэтому и прожка тормозит. И поэтому вызов ProcessMessages и приводит прогу в чувства. Поэтому и

Цитата:
прога виснет, но поток выполняется

--- прога как попадает в цикл, так, пока все не скопируется, вертится там без остановок -> поток сжирает все процессорное время и прога виснет, т.к. кроме копирования никаким потокам места не остается. Короче, как я уже писал тебе в другой теме --- Sleep(1) - самое простое решение --- поток "останавливается" на указанное в аргументе кол-во микросекунд и сис-ма может передать управление к-нибудь другому потоку, если есть претенденты. 1 мкс сис-ме вполне достаточно, чтобы дать поработать другим потокам. Торможения практически не заметишь.

246
18 апреля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by kot_
И STL тут каким боком? :)


или я туплю или давно не программировал...

1
19 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by GIZMO
или я туплю или давно не программировал...


Стандартный потоковый ввод-вывод(вначале stdio, затем iostream class library) не одно и тоже что стандартная библиотека шаблонов. :) тебя запутало скорее всего STD и STL, кроме того, шаблоном на основе потоков часто любят иллюстрировать область применения STL. Но в принципе это не критично, и возможно на сегодняшний день библиотека более интенсивно использует STL.

335
19 апреля 2006 года
enola
379 / / 25.01.2005
Вообщем сделал вот так:
 
Код:
BufferSize = 512;

    // ....
    // ....
   
    Synchronize(UpdatePosition);    

    Sleep(1);


и стало гораздо лучше. Но является ли данное решения правильным?
1
19 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by enola
Вообщем сделал вот так:
 
Код:
BufferSize = 512;

    // ....
    // ....
   
    Synchronize(UpdatePosition);    

    Sleep(1);


и стало гораздо лучше. Но является ли данное решения правильным?


Нет решений правильных или не правильных - есть уместные в данной конкретной ситуации. Если в данной задаче это решает проблему и не создаст новых - это правильно. Скорее всего, возникает конфликт доступа между двумя потоками - и решить ее можно двумя способами - первый слипом, или же необходимо писать потокобезопасный код. Это более правильно - если это оправдано.

335
19 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by kot_
Нет решений правильных или не правильных - есть уместные в данной конкретной ситуации. Если в данной задаче это решает проблему и не создаст новых - это правильно. Скорее всего, возникает конфликт доступа между двумя потоками - и решить ее можно двумя способами - первый слипом, или же необходимо писать потокобезопасный код. Это более правильно - если это оправдано.



Мда что-то действительно конфликтик в потоках, а как решить?
Слип это что такое?

324
19 апреля 2006 года
AndreySar
532 / / 01.08.2004
Цитата:
Originally posted by enola
Мда что-то действительно конфликтик в потоках, а как решить?
Слип это что такое?



Sleep() приостанавливает выполнение на потока не определенное время, в этот промежуток времени потоку не выделяется процессорное время

1
19 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by enola
Мда что-то действительно конфликтик в потоках, а как решить?
Слип это что такое?


Есть семафоры, мьютексы, объекты событий, функции ожидания - это инструменты, которые можно использовать при разрешении конфликтов потоков. В твоем случае - это возможно и не надо (точнее может здорово усложнить задачу) - вполне достаточно приостановить поток который занимает чрезмерно ресурсы процессора. Примеры работы с потоками можно посмотреть в папке $(BCB)\Examples\App\Threads.

335
21 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by AndreySar
Sleep() приостанавливает выполнение на потока не определенное время, в этот промежуток времени потоку не выделяется процессорное время



почему рекомендуют использовать Sleep(), а не ProcessMessage()?

335
21 апреля 2006 года
enola
379 / / 25.01.2005
Если делаю вот так:
 
Код:
File = new TFileThread(true);
    File->FreeOnTerminate = false;
    File->Resume();
    File->WaitFor();
    delete File;

программка в таком случае ждет завершения потока, но опять все висит.

А если вот так:
 
Код:
File = new TFileThread(true);
    File->FreeOnTerminate = true;
    File->Resume();

то соответственно не ждет :( , но и не висит.

Хотя в обоих случаях в методе Execute() стоит Sleep(1).

А задача состоит в следующем: необходимо, чтобы запускался поток, а программа ждала его завершения, при этом не подвисая.
Подскажите как решить проблему?
246
21 апреля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by enola
А задача состоит в следующем: необходимо, чтобы запускался поток, а программа ждала его завершения, при этом не подвисая.
Подскажите как решить проблему?


Так не получится, подождать завершения потока можно передав ф-ии WaitForSingleObject() хендл потока она будет ждать когда поток завершится и только после этого вернет управление в вызывающий поток (подозреваю, что тоже делает File->WaitFor();). Все это время вызывающий (у тебя это основной) поток будет "спать" (и никакой обработки цикла сообщений не будет). Чего хочешь получить в итоге, сформулируй задачу еще раз.

335
21 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by GIZMO
Чего хочешь получить в итоге, сформулируй задачу еще раз.


Ну я же вроде написал :):

Цитата:
А задача состоит в следующем: необходимо, чтобы запускался поток, а программа ждала его завершения, при этом не подвисая.



Но не вопрос, скажу по-другому:
я хочу чтобы по некоторому событию у меня копировался файл в потоке, но при этом программа не подвисала и ждала завершения потока. Вот как это реализовать?

Скажем по событию кнопки, происходит следующее:

Код:
File = new TFileThread(true);
    File->FreeOnTerminate = false;
    File->Resume();
    File->WaitFor();
    delete File;

    // апосля дальше некоторый код
    // который ждал бы завершения потока
    .....
   
    // тут еще один поток
    // опять необходимо ожидание завершения
246
21 апреля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by enola
Но не вопрос, скажу по-другому:
я хочу чтобы по некоторому событию у меня копировался файл в потоке, но при этом программа не подвисала и ждала завершения потока. Вот как это реализовать?
[/code]


Никак (или я тебя не совсем понимаю). Уже говорил если пустить поток и ждать его завершения, как ты хочешь, то основной поток при этом работать не будет (соответственно не идет обработка цикла сообщений т.е. программа подвисает). Можно пустить поток для копирования файла и при завершении копирования отправить основному потоку сообщение, а?

335
21 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by GIZMO
Никак (или я тебя не совсем понимаю). Уже говорил если пустить поток и ждать его завершения, как ты хочешь, то основной поток при этом работать не будет (соответственно не идет обработка цикла сообщений т.е. программа подвисает). Можно пустить поток для копирования файла и при завершении копирования отправить основному потоку сообщение, а?


:(

Мне нужно чтобы один поток копировал файл, потом прога парсила файл, а потом эти данные передавались во второй поток, где будут обрабатываться! Как такую задачу решить?

8.7K
21 апреля 2006 года
Rubicon
55 / / 28.10.2005
а что значит "ждала но не подвисала"? Как она должна ждать? У тебя ведь только 2 потока: основной и файловый, если ты хочешь, чтобы основной поток ждал завершения файлового, его придется тормознуть...
Можно по-другому сделать: тот код, который должен ожидать завершения файлового потока, выполнять в отдельном (уже 3ем) потоке, тогда тормозить будешь этот 3й поток, а основной будет жить.

Или еще так: помести "ожидающий" код, в файловый поток, чтобы он выполнился после завершения копирования файла (куда-нибудь в конец Execute) --- и программа не повиснет и ждать будет.
335
21 апреля 2006 года
enola
379 / / 25.01.2005
млин ерунда какая-то!

Вот какую логику преследую (может не совсем уместная):
1. Часики - отдельный поток, чтоб их так, всегда ходили, не подтормаживали (хотя в данной ситуации уж незнаю как и быть)
2. Копирование файла - отдельный поток, тут копируется файл по сети, файл большой, скорость по сетке никакая (dialup)
3. Парсинг файла - основной поток (сама программа)
4. Обработка полученного файла - отдельный поток, длительные вычисления.

Хочется увидеть "на выходе":
Первый поток всегда работает, т.е. всю "жизнь" программы, по клике на кнопке запускается второй поток, копируется файлик, по окончании копирования, парсится, потом полученные данные передаются в 4 поток и обрабатываются! Во как.

Как я понял одно из решений затолкать 2 поток, парсинг файла и 4 поток в новый поток и там все делать?
585
21 апреля 2006 года
honeybeer
297 / / 06.09.2004
Цитата:
Originally posted by enola
млин ерунда какая-то!

Вот какую логику преследую (может не совсем уместная):
1. Часики - отдельный поток, чтоб их так, всегда ходили, не подтормаживали (хотя в данной ситуации уж незнаю как и быть)
2. Копирование файла - отдельный поток, тут копируется файл по сети, файл большой, скорость по сетке никакая (dialup)
3. Парсинг файла - основной поток (сама программа)
4. Обработка полученного файла - отдельный поток, длительные вычисления.

Хочется увидеть "на выходе":
Первый поток всегда работает, т.е. всю "жизнь" программы, по клике на кнопке запускается второй поток, копируется файлик, по окончании копирования, парсится, потом полученные данные передаются в 4 поток и обрабатываются! Во как.

Как я понял одно из решений затолкать 2 поток, парсинг файла и 4 поток в новый поток и там все делать?


Мне кажется, что столько потоков совершенно ни к чему

335
21 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by honeybeer
Мне кажется, что столько потоков совершенно ни к чему



А как тогда решать задачу?
До этого времени у меня все было реализовано в основном потоке программы, но тогда появляются мелкие тормоза, проблемы с интерфейсом, когда файлик по сети копируется и т.п..
Когда идет обработка данных, еще хуже, для примера нажимаешь на заголовок окна программы и все вычисления подвисают, естественно если обработка загнана в поток такого не наблюдается, вот и решил так сделать.

406
21 апреля 2006 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by enola

Вот какую логику преследую (может не совсем уместная):
1. Часики - отдельный поток, чтоб их так, всегда ходили, не подтормаживали (хотя в данной ситуации уж незнаю как и быть)
2. Копирование файла - отдельный поток, тут копируется файл по сети, файл большой, скорость по сетке никакая (dialup)
3. Парсинг файла - основной поток (сама программа)
4. Обработка полученного файла - отдельный поток, длительные вычисления.



Вот как бы надо это зделать используя только один поток и еще 2 по необходимости.
Во время бездействия будет только один поток.

1 имеем 1ый поток - основной для интерфейса и часов
2. Для часов отдельный поток не нужен,будем в 1ом потке отлавливать WM_TIMER и сменять время
3. Когда необходимо копирование файла создаем ждущий поток(2й поток) отсюда создаем 3й поток
и во втором ждем завершения операции копирования 3его потока с помощью WaitForSingleObject
4. Когда 3ий поток завершает копирование и уничтожается мы это отлавливаем по тому что вернул
WaitForSingleObject и запускаем снова 3ий поток но уже для вычислительных операций и снова ждем из второго. попутно можем из 2го потока выдавать какие нить уведомления пользователю. После того как вычисления завершились,3й поток уничтожается,2й поток делает завершающие операции(уведомляет пользователя) и сам завершается.
5. Теперь у нас снова токо 1 поток. Если необходимо получить файл возвращяемся к пункту 3...

335
21 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by vitaly2003s
Вот как бы надо это зделать используя только один поток и еще 2 по необходимости.
Во время бездействия будет только один поток.

1 имеем 1ый поток - основной для интерфейса и часов
2. Для часов отдельный поток не нужен,будем в 1ом потке отлавливать WM_TIMER и сменять время
3. Когда необходимо копирование файла создаем ждущий поток(2й поток) отсюда создаем 3й поток
и во втором ждем завершения операции копирования 3его потока с помощью WaitForSingleObject
4. Когда 3ий поток завершает копирование и уничтожается мы это отлавливаем по тому что вернул
WaitForSingleObject и запускаем снова 3ий поток но уже для вычислительных операций и снова ждем из второго. попутно можем из 2го потока выдавать какие нить уведомления пользователю. После того как вычисления завершились,3й поток уничтожается,2й поток делает завершающие операции(уведомляет пользователя) и сам завершается.
5. Теперь у нас снова токо 1 поток. Если необходимо получить файл возвращяемся к пункту 3...



интересно.
можешь простенькую реализацию накидать, если не сложно:
1. С часами, я по WM_TIMER никогда не делал, и с сообщениями тоже плохо знаком.
2. С потоками.
заранее благодарен.

Вот что я нашел на rsdn:

Код:
static volatile long nLock;

    if (InterlockedExchange (&nLock, 1))
        return;

    File = new TFileThread(true);

    File->Resume();

    Wait(File);

    InterlockedExchange (&nLock, 0);


и реализация функции Wait:
Код:
void TMainForm::Wait(HANDLE hEvent)
{
    DWORD nHandleCount = 1; //we wait only on hEvent

    while (TRUE)
    {
        DWORD nResult;
        MSG msg;

        //dispatch message from queue
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                return;
            DispatchMessage(&msg);
        }


        //wait for event or message in queue
        nResult = MsgWaitForMultipleObjects(nHandleCount,
                                             &hEvent,
                                             FALSE,
                                             INFINITE,
                                             QS_PAINT|QS_POSTMESSAGE);

        if (nResult < (WAIT_OBJECT_0 + 1))
            break; //event is signalled

        //otherwise msg arrived
        //just continue to loop
    }
}


правда после выполнения потока функция Wait() не заканчивает свою работу, что конечно хотелось бы, я так полагаю ждет сообщения. Какого подскажите?
А так все потоки живут нормально и интерфейс прорисовывается и программа ждет окончания потока, только дождаться не может :)
1
21 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by enola

правда после выполнения потока функция Wait() не заканчивает свою работу, что конечно хотелось бы, я так полагаю ждет сообщения. Какого подскажите?
А так все потоки живут нормально и интерфейс прорисовывается и программа ждет окончания потока, только дождаться не может :)


Все зависит от сложности задачи - если задача - часы и копирование(по завершении парсинг) - вполне достаточно 2-х классов потока - один копирует файл, по завершении посылает сообщение окну приложения. После этого стартует второй объект класса потока - парсит - посылает уведомление и т.д. У меня так работает программа которая копирует файлы с фтп и производит их занесение в базу(правда у меня помещение в базу происходит в основном потоке программы - если захочешь переделаешь). Может это то что тебе необходимо?

335
21 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by kot_
Все зависит от сложности задачи - если задача - часы и копирование(по завершении парсинг) - вполне достаточно 2-х классов потока - один копирует файл, по завершении посылает сообщение окну приложения. После этого стартует второй объект класса потока - парсит - посылает уведомление и т.д. У меня так работает программа которая копирует файлы с фтп и производит их занесение в базу(правда у меня помещение в базу происходит в основном потоке программы - если захочешь переделаешь). Может это то что тебе необходимо?



можешь исходники кинуть?

 
Код:
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                return;
            DispatchMessage(&msg);
        }


подскажите как сделать чтобы данная конструкция получала, чего ожидает, т.е. выходила? Какое ей сообщение нужно и как его послать или как сделать чтобы она его получила?
1
21 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by enola
можешь исходники кинуть?


Держи. Фрегмент кода который запускает поток:

Код:
void __fastcall TfmMain::tmLoadTimer(TObject *Sender)
{
 if(GlobalClose){
  CloseQuery();
  return;
 }
 lbCurrent->Caption = "Received files from FTP";
 tmLoad->Enabled = false;
 lbMin->Caption = IntToStr(MinutesBetween(StrToDateTime(lbStart->Caption),Now()));
 TreadFTPReceiv(FTPServer,FTPDirIn,HostUser,HostPass,WorkDir);
 Application->ProcessMessages();
}

фрагмент который обрабатывает сообщения:
Код:
void TfmMain::ReceivedFiles(TMessage &Msg){
 if(Msg.Msg==WM_FILERECEIV){
    tmLoad->Enabled = false;
    dmLoad = new TdmLoad(0);
    lbCurrent->Caption = "Connect to DB";
    dmLoad->adoConnect->Connected = false;
    WideString Connect = "Provider=SQLOLEDB.1;Password="+WideString(Pass)+";Persist Security Info=True;User ID="+WideString(User)+";Initial Catalog=credcom;Data Source="+WideString(Server)+";Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=M30X;Use Encryption for Data=False;Tag with column collation when possible=False";
    dmLoad->adoConnect->ConnectionString = Connect;
    dmLoad->adoConnect->Connected = true;
    lbCurrent->Caption = "Send data to DB";
    LoadPackets();
    lbCurrent->Caption = "Wait connection";
     dmLoad->adoConnect->Connected = false;
    delete dmLoad;
  }
  else if(Msg.Msg==WM_START_TIMERS){

   tmLoad->Enabled = true;
   lbCurrent->Caption = "Wait connection";


  }
}
/*
*Загрузка пакетов в базу
*Функция проверяет директорию, указанную
*в качестве рабочей
*/
bool TfmMain::LoadPackets()
{
 String tmpFind = WorkDir+"*.*";
 TSearchRec sr;
 try{
 if(FindFirst(tmpFind,faAnyFile, sr) == 0){
  do
    {
    if(sr.Attr&faDirectory){
    ;
    }
    else{

      SendDataToBase(sr.Name);
    }
  }while(FindNext(sr)==0);
 }
}
__finally{
 FindClose(sr);
 SendMessage(Handle,WM_START_TIMERS,NULL,NULL);
}
 return true;
}

с остальным я думаю разберешься.
246
22 апреля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by enola
правда после выполнения потока функция Wait() не заканчивает свою работу, что конечно хотелось бы, я так полагаю ждет сообщения. Какого подскажите?


Дык черным по английски написано, что ждет - WM_QUIT от PostThreadMessage:)
Только зачем тебе такая организация потока. Сделай нормально, что бы поток копировал файл и усе. А если главному потоку(кот. рулит MainForm) надо знать, что копирование завершено, то пошли в главную форму свое сообщение.

335
22 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by GIZMO
Дык черным по английски написано, что ждет - WM_QUIT от PostThreadMessage:)
Только зачем тебе такая организация потока. Сделай нормально, что бы поток копировал файл и усе. А если главному потоку(кот. рулит MainForm) надо знать, что копирование завершено, то пошли в главную форму свое сообщение.



Да я еще вчера понял какого сообщения ждет, не надо быть гуру, чтобы понять, и понял чем его посылать только вот не получилось у меня, может устал, а может потому что никогда с сообщениями дело не имел.

Я с превеликим удовольствием сделаю именно так как ты говоришь, только вот с сообщениями я не очень.
Будь так добр напиши пример, а я уже дальше начну смотреть. Спасибо.

246
22 апреля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by enola
Да я еще вчера понял какого сообщения ждет, не надо быть гуру, чтобы понять, и понял чем его посылать только вот не получилось у меня, может устал, а может потому что никогда с сообщениями дело не имел.

Я с превеликим удовольствием сделаю именно так как ты говоришь, только вот с сообщениями я не очень.
Будь так добр напиши пример, а я уже дальше начну смотреть. Спасибо.


Вот типа этого, проверки поставишь сам.

335
22 апреля 2006 года
enola
379 / / 25.01.2005
Спасибо всем кто принял участие в дискуссии!!!

вот решение на котором я остановился:

создание потока и его запуск, запуск ожидающей функции:
 
Код:
// Создание потока файл
    File = new TFileThread(true);

    // Запуск потока
    File->Resume();

    // Ожидание потока
    Wait((void *)File->Handle);


функция ожидания (была найдена на rsdn.ru, автор ссылается на MSDN):
Код:
void Wait(HANDLE hEvent)
{
    DWORD dwRet;
    MSG msg;

    while(1)
    {
        dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);

        if (dwRet == WAIT_OBJECT_0)
            return;    // The event was signaled

        if (dwRet != WAIT_OBJECT_0 + 1)
            break;          // Something else happened

        // There is one or more window message available. Dispatch them
        while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
                return; // Event is now signaled.
        }
    }
}
1
22 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by enola
Спасибо всем кто принял участие в дискуссии!!!

вот решение на котором я остановился:

функция ожидания (была найдена на rsdn.ru, автор ссылается на MSDN):
 
Код:
dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);


Мне все же кажется что использование функции ожидания в данном случае слишком расточительно. Ведь потоки по сути не конкурируют за ресурсы - выполнение идет последовательно. ИМХО

335
22 апреля 2006 года
enola
379 / / 25.01.2005
Цитата:
Originally posted by kot_
Мне все же кажется что использование функции ожидания в данном случае слишком расточительно. Ведь потоки по сути не конкурируют за ресурсы - выполнение идет последовательно. ИМХО



ну а что делать?!

1
22 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by enola
ну а что делать?!


??? Ну а чем отправка и обработка сообщений от потоков не дело? Как я указал выше - это лично мое мнение - и мне интересно услышать обоснование другого мнения - в данной задаче (в объеме приведенном тобой) дествия должны выполнятся строго последовательно и конкуренции за ресурсы не предполагается - нужно ли использовать при этом функции привилигированного доступа? Чем хуже такой например вариант:

Код:
SendMessage(WM_SOMEMESSAGEPAINT,0,FileSize);
while(In)
    {
        // Считывание данных в буфер
        In.read(DataBuffer, BufferSize);
        Readed = In.gcount();
        if(Readed > 0)
            Out.write(DataBuffer, Readed);

        // Подсчет кол-ва считанных символов
        SymCount += Readed;

        // Изменение позиции прогрессбара
       // Pos = SymCount * 100 / FileSize;
       SendMessage(WM_SOMEMESSAGEPAINT,SymCount,FileSize);
    }

    // Закрытие файлов
    In.close();
    Out.close();
SendMessage(WM_MYMESSAGEOK,SymCount,FileSize);
}

и всех делов? Ну естественно рабочая реализация должна быть сложнее - надо учесть ошибки чтения и пр. Но просто мне непонятно - нафига тебе ждать ЗАВЕРШЕНИЯ потока???? А если файл не прочтен? А если сеть лягла? Тебе нужно только УВЕДОМЛЕНИЕ о благополучно выполненной операции - причем по времени это не критично - ты же читаешь файл а не данные реального режима? Четы паришься? Определи сообщения об ошибках и сбоях и сообщение о нормальном завершении операции - и все. Зачем тебе дергать систему и переводить ее раз за разом в режим ядра, даже не зная будет ли от этого толк? :)
З.Ы. Кстати со Светлым Воскресением всех форумчан.Через 2 часа провозгласят: "Христос Воскресе". :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог