项目简介和code见《同步异步和阻塞2-测试小项目

1. 实现

1> 异步线程IO处理

unsigned CAsyncIO::ThreadWork()
{

    int nRet = IO();

    //map is better than array at here, but it need STL
    unsigned uTid = GetCurrentThreadId();
    for (int i = 0; i < sizeof(m_uThreadArray) / sizeof(m_uThreadArray[0]); i++)
    {
        //Because handle is not same at different thread, so it need use tid to associate the thread and IO caller.
        if (uTid == m_uThreadArray[i])
        {
            NotifyProgress(100, i);
            NotifyResult(nRet, i);
        }
    }

    return    nRet;
}

线程调用完IO后,直接通知UI结果。

 

2> OnStart()

bool CAsyncIO::OnStart()
{
    OnStop();
    for (int i = 0; i < sizeof(m_uThreadArray) / sizeof(m_uThreadArray[0]); i++)
    {
        HANDLE hThread = StartThread();
        m_hThreadHandleArray[i] = hThread;
        m_uThreadArray[i] = ::GetThreadId(hThread);
    }

    return    true;
}

OnStart()只要把线程启动处理IO即可返回,这样就不会再阻塞UI主线程,”Start”按钮在返回后会变为”Stop”。

 

3> Stop的实现

由于IO不再阻塞主线程,所以“Stop”按钮变为可用,Stop的实现就变得有意义。

bool CAsyncIO::OnStop()
{
    for (int i = 0; i < sizeof(m_hThreadHandleArray) / sizeof(m_hThreadHandleArray[0]); i++)
    {
        HANDLE hThread = m_hThreadHandleArray[i];
        if (hThread)
        {
            TerminateThreadUntilExit(hThread);
            ::CloseHandle(hThread);
            m_hThreadHandleArray[i] = NULL;
        }
    }

    return    true;
}

这里Stop()的实现仅仅是简单的Terminate掉线程,由于直接终止线程,无法知道线程所处的状态,会出现什么情况无法预知,有时会出现莫名奇妙的问题,微软也是不推荐的,需谨慎使用。

 

2. 测试

点击”Start”按钮后,虽然IO没有处理完毕,但是按钮立即变为可用的”Stop”,同时UI窗口也是可以随意移动操作的。

image

异步非阻塞模式不阻塞UI主线程,用户体验上是最好的。同时在并发处理上也相对同步非阻塞模式简单,当然由于需要在IO处理完毕后通过callback通知UI主线程,这必然会涉及到线程同步的问题,线程同步是个非常头疼的问题,在异步模式带来的好处不是远远大于同步模式的情况下,其带来的问题会远远大于同步模式。

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!