VC大牛请进

SKATE11 2013-09-18 06:40:57
最近在做音乐播程序 音乐播放分为两个程序 一个进程负责搜索音乐文件 一个进程负责播放音乐文件 搜索文件的那个进程创建一个线程进行搜索 并在此线程用一个列表控件列出加载到的音乐文件 然后点击列表项创建播放进程 当加载音乐很多的时候 我从音乐播放界面 返回到列表界面 列表界面无法刷新 UpdateWindow()也不行 只有等到列表控件加载完成才行,求解。
...全文
438 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-09-22
  • 打赏
  • 举报
回复
学会使用Spy++跟踪Windows消息。 VC6: Setting a Breakpoint on a Message Received by a Windows Function You can set message breakpoints to stop the debugger when a particular WndProc function message is received. Note Message breakpoints work only on x86- or Pentium-based systems. To set a breakpoint on a message From the Edit menu, click Breakpoints. The Breakpoints dialog box appears. Click the Messages tab. In the Break At WndProc text box, type the name of the Windows function. If you are setting a breakpoint during a debug session, the list contains the exported functions in your project. In the Set One Breakpoint For Each Message To Watch list box, select the message. To set another breakpoint, press ENTER, and then repeat steps 3 and 4. The Breakpoints list displays the currently active breakpoints. Click OK to set the breakpoints. Note If you interrupt execution while Windows or other system code is running, the results can be unpredictable.
赵4老师 2013-09-22
  • 打赏
  • 举报
回复
某个地方该加 Sleep(300); 或 MSG msg; if (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } 没加而已罢了。
SKATE11 2013-09-22
  • 打赏
  • 举报
回复
引用 10 楼 unituniverse2 的回复:
需要知道的是消息一定是一条接一条的处理的,而如果当前在处理消息的时候其他消息都得不到处理的。列表添加项和界面重绘并不是同一条消息。所以你别在一条消息处理过程里一次性的添加所有的项,那样项多了自然会卡死,用了多线程什么的都是浪费、没有任何本质上的不同。你不要那么贪心。应该在每一次消息处理有限个数的几条项就马上返回。如果没处理完在下次再发的消息里继续处理。。。直到全部添加完毕。
这个解释貌似最合理的 但是我不是理解 列表控件怎么会把所依附的对话框消息处理给阻塞掉了 列表加载文件之前SetRedraw(FALSE) 循环加载完毕后才SetRedraw(TRUE) 此时主对话框无法处理任何消息 直到加载完毕SetRedraw(TRUE)后才恢复
SKATE11 2013-09-22
  • 打赏
  • 举报
回复
引用 19 楼 zhao4zhong1 的回复:
仅供参考:
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#ifdef WIN32
    #pragma warning(disable:4996)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
    #include <windows.h>
    #include <process.h>
    #include <io.h>
    #define  MYVOID             void
    #define  vsnprintf          _vsnprintf
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  MYVOID             void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
    Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
    usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;

    if (NULL==pszFmt||0==pszFmt[0]) return;
    vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
        } else {
            fclose(flog);
        }
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
#define ASIZE    200
#define BSIZE    240
#define CSIZE      2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
    int  head;
    int  tail;
    int  size;
    char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
    int i,j,k;
    char binstr[80];

    Lock(&cs_HEX);
    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%03d %04x -",cn,i);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            Log("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        Log("%s\n",binstr);
    }
    Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    lent=0;
    Lock(cs);
    if (fbuf->size>=len) {
        lent=len;
        if (fbuf->head+lent>BSIZE) {
            len1=BSIZE-fbuf->head;
            memcpy(buf     ,fbuf->data+fbuf->head,len1);
            len2=lent-len1;
            memcpy(buf+len1,fbuf->data           ,len2);
            fbuf->head=len2;
        } else {
            memcpy(buf     ,fbuf->data+fbuf->head,lent);
            fbuf->head+=lent;
        }
        fbuf->size-=lent;
    }
    Unlock(cs);
    return lent;
}
MYVOID thdB(void *pcn) {
    char        *recv_buf;
    int          recv_nbytes;
    int          cn;
    int          wc;
    int          pb;

    cn=(int)pcn;
    Log("%03d thdB              thread begin...\n",cn);
    while (1) {
        sleep_ms(10);
        recv_buf=(char *)Cbuf;
        recv_nbytes=CSIZE;
        wc=0;
        while (1) {
            pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
            if (pb) {
                Log("%03d recv %d bytes\n",cn,pb);
                HexDump(cn,recv_buf,pb);
                sleep_ms(1);
            } else {
                sleep_ms(1000);
            }
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    Lock(cs);
    lent=len;
    if (fbuf->size+lent>BSIZE) {
        lent=BSIZE-fbuf->size;
    }
    if (fbuf->tail+lent>BSIZE) {
        len1=BSIZE-fbuf->tail;
        memcpy(fbuf->data+fbuf->tail,buf     ,len1);
        len2=lent-len1;
        memcpy(fbuf->data           ,buf+len1,len2);
        fbuf->tail=len2;
    } else {
        memcpy(fbuf->data+fbuf->tail,buf     ,lent);
        fbuf->tail+=lent;
    }
    fbuf->size+=lent;
    Unlock(cs);
    return lent;
}
MYVOID thdA(void *pcn) {
    char        *send_buf;
    int          send_nbytes;
    int          cn;
    int          wc;
    int           a;
    int          pa;

    cn=(int)pcn;
    Log("%03d thdA              thread begin...\n",cn);
    a=0;
    while (1) {
        sleep_ms(100);
        memset(Abuf,a,ASIZE);
        a=(a+1)%256;
        if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
        send_buf=(char *)Abuf;
        send_nbytes=ASIZE;
        Log("%03d sending %d bytes\n",cn,send_nbytes);
        HexDump(cn,send_buf,send_nbytes);
        wc=0;
        while (1) {
            pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
            Log("%03d sent %d bytes\n",cn,pa);
            HexDump(cn,send_buf,pa);
            send_buf+=pa;
            send_nbytes-=pa;
            if (send_nbytes<=0) break;//
            sleep_ms(1000);
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int main() {
#ifdef WIN32
    InitializeCriticalSection(&cs_log);
    InitializeCriticalSection(&cs_HEX );
    InitializeCriticalSection(&cs_BBB );
#else
    pthread_t threads[2];
    int threadsN;
    int rc;
    pthread_mutex_init(&cs_log,NULL);
    pthread_mutex_init(&cs_HEX,NULL);
    pthread_mutex_init(&cs_BBB,NULL);
#endif
    Log("Start===========================================================\n");

    BBB.head=0;
    BBB.tail=0;
    BBB.size=0;

#ifdef WIN32
    _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
    _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
#else
    threadsN=0;
    rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
    rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif

    if (!access("No_Loop",0)) {
        remove("No_Loop");
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    while (1) {
        sleep_ms(1000);
        if (No_Loop) break;//
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    sleep_ms(3000);
    Log("End=============================================================\n");
#ifdef WIN32
    DeleteCriticalSection(&cs_BBB );
    DeleteCriticalSection(&cs_HEX );
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_BBB);
    pthread_mutex_destroy(&cs_HEX);
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
SKATE11 2013-09-22
  • 打赏
  • 举报
回复
引用 18 楼 lm_whales 的回复:
1000多个文件 花了20几秒,一次处理,1000多个文件,20几秒,虽然不快,也不是非常慢,只是这20几秒,界面没有丝毫响应,所以非常卡。 你,无论是多线程,还是处理消息循环,让界面有个相应,可能30几秒才处理完1000多个文件; 但是界面是活动的,用户体验就比较好,界面不会卡。 一味求快,并不是好程序,要考虑人性化因素; 界面卡死,对于用户来说,是个大问题。 相对来说,节省的那点时间,反而不算什么; 用户对此不会有啥感觉,毕竟要处理1000多个文件的问题,数量还是蛮多的。
今天找出问题根源了 从其它界面返回时卡住其它界面没法刷新列表界面是因为我设置了列表控件:SetRedraw(FALSE),直到加载完文件运行SetRedraw(TRUE)后窗口才可以处理消息 这就更纳闷了 列表控件的SetRedraw(FALSE)居然会导致依附的对话框窗口无法处理消息了,而且我列表控件的加载还是放在子线程里面做。
赵4老师 2013-09-22
  • 打赏
  • 举报
回复
仅供参考:
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#ifdef WIN32
    #pragma warning(disable:4996)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
    #include <windows.h>
    #include <process.h>
    #include <io.h>
    #define  MYVOID             void
    #define  vsnprintf          _vsnprintf
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  MYVOID             void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
    Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
    usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;

    if (NULL==pszFmt||0==pszFmt[0]) return;
    vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
        } else {
            fclose(flog);
        }
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
#define ASIZE    200
#define BSIZE    240
#define CSIZE      2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
    int  head;
    int  tail;
    int  size;
    char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
    int i,j,k;
    char binstr[80];

    Lock(&cs_HEX);
    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%03d %04x -",cn,i);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            Log("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        Log("%s\n",binstr);
    }
    Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    lent=0;
    Lock(cs);
    if (fbuf->size>=len) {
        lent=len;
        if (fbuf->head+lent>BSIZE) {
            len1=BSIZE-fbuf->head;
            memcpy(buf     ,fbuf->data+fbuf->head,len1);
            len2=lent-len1;
            memcpy(buf+len1,fbuf->data           ,len2);
            fbuf->head=len2;
        } else {
            memcpy(buf     ,fbuf->data+fbuf->head,lent);
            fbuf->head+=lent;
        }
        fbuf->size-=lent;
    }
    Unlock(cs);
    return lent;
}
MYVOID thdB(void *pcn) {
    char        *recv_buf;
    int          recv_nbytes;
    int          cn;
    int          wc;
    int          pb;

    cn=(int)pcn;
    Log("%03d thdB              thread begin...\n",cn);
    while (1) {
        sleep_ms(10);
        recv_buf=(char *)Cbuf;
        recv_nbytes=CSIZE;
        wc=0;
        while (1) {
            pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
            if (pb) {
                Log("%03d recv %d bytes\n",cn,pb);
                HexDump(cn,recv_buf,pb);
                sleep_ms(1);
            } else {
                sleep_ms(1000);
            }
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    Lock(cs);
    lent=len;
    if (fbuf->size+lent>BSIZE) {
        lent=BSIZE-fbuf->size;
    }
    if (fbuf->tail+lent>BSIZE) {
        len1=BSIZE-fbuf->tail;
        memcpy(fbuf->data+fbuf->tail,buf     ,len1);
        len2=lent-len1;
        memcpy(fbuf->data           ,buf+len1,len2);
        fbuf->tail=len2;
    } else {
        memcpy(fbuf->data+fbuf->tail,buf     ,lent);
        fbuf->tail+=lent;
    }
    fbuf->size+=lent;
    Unlock(cs);
    return lent;
}
MYVOID thdA(void *pcn) {
    char        *send_buf;
    int          send_nbytes;
    int          cn;
    int          wc;
    int           a;
    int          pa;

    cn=(int)pcn;
    Log("%03d thdA              thread begin...\n",cn);
    a=0;
    while (1) {
        sleep_ms(100);
        memset(Abuf,a,ASIZE);
        a=(a+1)%256;
        if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
        send_buf=(char *)Abuf;
        send_nbytes=ASIZE;
        Log("%03d sending %d bytes\n",cn,send_nbytes);
        HexDump(cn,send_buf,send_nbytes);
        wc=0;
        while (1) {
            pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
            Log("%03d sent %d bytes\n",cn,pa);
            HexDump(cn,send_buf,pa);
            send_buf+=pa;
            send_nbytes-=pa;
            if (send_nbytes<=0) break;//
            sleep_ms(1000);
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int main() {
#ifdef WIN32
    InitializeCriticalSection(&cs_log);
    InitializeCriticalSection(&cs_HEX );
    InitializeCriticalSection(&cs_BBB );
#else
    pthread_t threads[2];
    int threadsN;
    int rc;
    pthread_mutex_init(&cs_log,NULL);
    pthread_mutex_init(&cs_HEX,NULL);
    pthread_mutex_init(&cs_BBB,NULL);
#endif
    Log("Start===========================================================\n");

    BBB.head=0;
    BBB.tail=0;
    BBB.size=0;

#ifdef WIN32
    _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
    _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
#else
    threadsN=0;
    rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
    rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif

    if (!access("No_Loop",0)) {
        remove("No_Loop");
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    while (1) {
        sleep_ms(1000);
        if (No_Loop) break;//
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    sleep_ms(3000);
    Log("End=============================================================\n");
#ifdef WIN32
    DeleteCriticalSection(&cs_BBB );
    DeleteCriticalSection(&cs_HEX );
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_BBB);
    pthread_mutex_destroy(&cs_HEX);
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
lm_whales 2013-09-22
  • 打赏
  • 举报
回复
1000多个文件 花了20几秒,一次处理,1000多个文件,20几秒,虽然不快,也不是非常慢,只是这20几秒,界面没有丝毫响应,所以非常卡。 你,无论是多线程,还是处理消息循环,让界面有个相应,可能30几秒才处理完1000多个文件; 但是界面是活动的,用户体验就比较好,界面不会卡。 一味求快,并不是好程序,要考虑人性化因素; 界面卡死,对于用户来说,是个大问题。 相对来说,节省的那点时间,反而不算什么; 用户对此不会有啥感觉,毕竟要处理1000多个文件的问题,数量还是蛮多的。
unituniverse2 2013-09-21
  • 打赏
  • 举报
回复
最好还是用我10楼标出的方法,
SKATE11 2013-09-21
  • 打赏
  • 举报
回复
引用 14 楼 lm_whales 的回复:
添加一个项,很快吧! 这个过程很漫长,怎么会呢!!! 如果添加一个项,本身很慢,你无论怎么处理,也快不了。 添加一个项,是微秒级的吧! 估计你需要分隔出,计算代码,和界面代码。 计算代码,慢一点,没关系,可以开个线程全速跑,多核心就是好呀,这不就快起来了! 界面代码,只要能够及时刷新界面,及时响应消息,就可以了 --计算量不要太大-- 消息循环就是个,不停等待和处理消息的过程。 窗口函数--界面响应消息的函数--- 实际上,是被消息循环里面的代码,主要是DispatchMessage函数调用的。
1000多个文件 花了20几秒
lm_whales 2013-09-21
  • 打赏
  • 举报
回复
PS: 可以在消息响应函数里处理消息循环,效果类似多线程,但不如多线程代码干净。
lm_whales 2013-09-21
  • 打赏
  • 举报
回复
有不同,一次性添加,计算过程太长,时间卡在计算上,只有一次刷新,用户体验非常差。 多线程,分批添加,计算和界面不会互相卡,由于每次只更新一部分,界面相应也能够及时。 计算由于多线程,也能够加速,由于及时更新,用户体验会有很大改善。 当然如果仅仅是刷新界面,计算量不大,耗时很少,多线程就不必了。 循环添加,并运行消息循环就好。
unituniverse2 2013-09-21
  • 打赏
  • 举报
回复
引用 13 楼 SKATE11 的回复:
[quote=引用 5 楼 unituniverse2 的回复:] 你要知道多线程的目的是什么 多线程的目的之一是释放主线程的资源占用,使得主线程能迅速的响应消息。 而如果达不到这个目的,用多线程除了增加程序编写和调试的复杂性以外却没有得到任何好处。 你的问题更有可能是消息排队。每一个线程分别拥有最多一个消息循环,而一个窗口将只属于一个固定的消息循环。如果有多个线程对一个窗口或线程消息循环发消息,消息响应并不会被异步、并行的处理,而是会自动的排队。一条消息过程处理完消息函数返回后,才会接着处理下一条消息,而其他线程如果用send方式发消息的话,在此期间是处于阻塞状态的。经常看到有人写消息过程中还另外加了信号量之类的东西应对多线程的消息响应,其实根本没有效果、必要。 至于你的问题,很可能是因为工作线程频繁的向主线程发送向列表插入项而导致主线程的用户输入消息一直处于排队状态而得不到处理,就跟失去响应差不多。注意“输入”广义的不但包括键盘鼠标触摸板游戏杆这些,还包括界面的重绘、刷新请求。虽然控件的内容发生了更改,但是这种更改因为无法重绘得不到及时处理,而不能反映在界面上。
主要问题就是一子线程在给列表控件添加项 这个过程很漫长 从其它界面返回到此界面时如果没添加完成就会卡住此界面[/quote] 给列表添加项其实都是窗口线程自己做的,不管你用了还是没用多线程。
lm_whales 2013-09-21
  • 打赏
  • 举报
回复
添加一个项,很快吧! 这个过程很漫长,怎么会呢!!! 如果添加一个项,本身很慢,你无论怎么处理,也快不了。 添加一个项,是微秒级的吧! 估计你需要分隔出,计算代码,和界面代码。 计算代码,慢一点,没关系,可以开个线程全速跑,多核心就是好呀,这不就快起来了! 界面代码,只要能够及时刷新界面,及时响应消息,就可以了 --计算量不要太大-- 消息循环就是个,不停等待和处理消息的过程。 窗口函数--界面响应消息的函数--- 实际上,是被消息循环里面的代码,主要是DispatchMessage函数调用的。
SKATE11 2013-09-21
  • 打赏
  • 举报
回复
引用 5 楼 unituniverse2 的回复:
你要知道多线程的目的是什么 多线程的目的之一是释放主线程的资源占用,使得主线程能迅速的响应消息。 而如果达不到这个目的,用多线程除了增加程序编写和调试的复杂性以外却没有得到任何好处。 你的问题更有可能是消息排队。每一个线程分别拥有最多一个消息循环,而一个窗口将只属于一个固定的消息循环。如果有多个线程对一个窗口或线程消息循环发消息,消息响应并不会被异步、并行的处理,而是会自动的排队。一条消息过程处理完消息函数返回后,才会接着处理下一条消息,而其他线程如果用send方式发消息的话,在此期间是处于阻塞状态的。经常看到有人写消息过程中还另外加了信号量之类的东西应对多线程的消息响应,其实根本没有效果、必要。 至于你的问题,很可能是因为工作线程频繁的向主线程发送向列表插入项而导致主线程的用户输入消息一直处于排队状态而得不到处理,就跟失去响应差不多。注意“输入”广义的不但包括键盘鼠标触摸板游戏杆这些,还包括界面的重绘、刷新请求。虽然控件的内容发生了更改,但是这种更改因为无法重绘得不到及时处理,而不能反映在界面上。
主要问题就是一子线程在给列表控件添加项 这个过程很漫长 从其它界面返回到此界面时如果没添加完成就会卡住此界面
unituniverse2 2013-09-20
  • 打赏
  • 举报
回复
需要知道的是消息一定是一条接一条的处理的,而如果当前在处理消息的时候其他消息都得不到处理的。列表添加项和界面重绘并不是同一条消息。所以你别在一条消息处理过程里一次性的添加所有的项,那样项多了自然会卡死,用了多线程什么的都是浪费、没有任何本质上的不同。你不要那么贪心。应该在每一次消息处理有限个数的几条项就马上返回。如果没处理完在下次再发的消息里继续处理。。。直到全部添加完毕。
unituniverse2 2013-09-20
  • 打赏
  • 举报
回复
引用 8 楼 lm_whales 的回复:
[quote=引用 7 楼 max_min_ 的回复:] 没必要用多进程 多线程吧! 你这个都是差不多需要一个一个完成的,一个线程就够了!效率高多了! 干嘛要搞那么进程线程的。有点浪费
1)及时显示 2)充分利用多核(加快计算速度) 3)抢CPU(一般不是一个进程,在运行) [/quote] 没有效果的。他的问题是怎样才能做到在添加项的同时仍然能够很好的响应用户输入和界面重绘。而由于消息机制的强制串行化机制,多线程在这里显然起不到任何效果。
lm_whales 2013-09-20
  • 打赏
  • 举报
回复
引用 7 楼 max_min_ 的回复:
没必要用多进程 多线程吧! 你这个都是差不多需要一个一个完成的,一个线程就够了!效率高多了! 干嘛要搞那么进程线程的。有点浪费
1)及时显示 2)充分利用多核(加快计算速度) 3)抢CPU(一般不是一个进程,在运行)
max_min_ 2013-09-20
  • 打赏
  • 举报
回复
没必要用多进程 多线程吧! 你这个都是差不多需要一个一个完成的,一个线程就够了!效率高多了! 干嘛要搞那么进程线程的。有点浪费
unituniverse2 2013-09-19
  • 打赏
  • 举报
回复
补充内容,省得你可能又问的: postmessage负责将消息投递到消息队列末端,投递期间并不处理消息。如果队列已满,则投递失败,此条消息永远的遗失。 sendmessage如果调用者是当前消息队列所在的线程,则相当于直接调用对应窗口的消息响应的过程函数;如果窗口的消息队列所在的线程不是调用者所在线程,则会导致插队。如果此时窗口过程正在处理某条其他什么消息,则调用者线程挂起,直到过程函数返回并调用GetMessage或者PeekMessage才开始处理调用者的消息。同样如果调用者的消息正在被处理中,调用者之外的其他线程(不包括消息循环所在的线程。因为该线程在处理消息)如果用send方式发送消息,同样也会被挂起。 还有点需要注意:处理消息的永远是消息循环所在的线程。其他线程不参与处理的。其他线程发送的消息被消息响应函数处理时,其实消息响应函数的调用者还是窗口线程而不是那个消息的发送线程。这一点是和线程创建回调函数不同的。
unituniverse2 2013-09-19
  • 打赏
  • 举报
回复
你要知道多线程的目的是什么 多线程的目的之一是释放主线程的资源占用,使得主线程能迅速的响应消息。 而如果达不到这个目的,用多线程除了增加程序编写和调试的复杂性以外却没有得到任何好处。 你的问题更有可能是消息排队。每一个线程分别拥有最多一个消息循环,而一个窗口将只属于一个固定的消息循环。如果有多个线程对一个窗口或线程消息循环发消息,消息响应并不会被异步、并行的处理,而是会自动的排队。一条消息过程处理完消息函数返回后,才会接着处理下一条消息,而其他线程如果用send方式发消息的话,在此期间是处于阻塞状态的。经常看到有人写消息过程中还另外加了信号量之类的东西应对多线程的消息响应,其实根本没有效果、必要。 至于你的问题,很可能是因为工作线程频繁的向主线程发送向列表插入项而导致主线程的用户输入消息一直处于排队状态而得不到处理,就跟失去响应差不多。注意“输入”广义的不但包括键盘鼠标触摸板游戏杆这些,还包括界面的重绘、刷新请求。虽然控件的内容发生了更改,但是这种更改因为无法重绘得不到及时处理,而不能反映在界面上。
加载更多回复(4)

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧