none
异步处理能否被模拟成同步的? RRS feed

  • 问题

  • int Read_ReadBlock(void* buffer, int offset, int size)
    {
        .....
        pFileData->readStream->Seek(offset);
    	DataReader^ dataReader = ref new DataReader(pFileData->readStream);
    	if(size < pFileData->readStream->Size)
    	{
    		task<unsigned int>(dataReader->LoadAsync(size)).then([](unsigned int numBytesLoaded)
    		{
    			int nlength = numBytesLoaded;
    			......  //读取数据处理
    			OutputDebugString(L"Loading\n");
    		});
    
                 //这里想等待异步的数据处理完成在做返回
    	      OutputDebugString(L"Waiting\n");
              return 1;
    	}
    
    	return 0;
    }
    上面的函数是一个库的回调函数,需要读取一段指定数据放在buf中返回给库的处理函数,因为库的读取是同步进行的,所以出现在回调函数返回的时候还没读到数据的问题,是否有办法将loadAsyn 模拟成 同步的处理?
    2012年7月5日 4:00

答案

  • 我的做法,不知好不好,也请版主指点。

    int CFileAgentWinRT::OpenAndReadTextFile( WCHAR* fileName,const WCHAR* &txt,UINT &size ,bool sync) // winrt UI thread always async
    {
    	// Create the event handle that will later signal when background processing has completed.
    	HANDLE processingHandle = CreateEventEx(
    		nullptr, // Default security attributes
    		nullptr, // Manual-reset event
    		false,   // Initial state is non-signaled
    		EVENT_ALL_ACCESS  // Allow other threads to interact with handle.
    		);
    	auto t=create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new String(fileName)))
    	.then([this](StorageFile^ file) {
    	return FileIO::ReadTextAsync(file);
    	},task_continuation_context::use_arbitrary())
    	.then([this,&txt,&size,processingHandle](task<String^> previousTask)
    	{
     		try
     		{
     			mReadText = previousTask.get();
     			txt = mReadText->Data();
     			size = mReadText->Length();
    			SetEvent(processingHandle);
     		}
     		catch (...)
     		{
    
     		}
     		return 1;
    	},task_continuation_context::use_arbitrary());
    
    	if (sync)
    		WaitForSingleObjectEx(processingHandle, 1000, false);
    	CloseHandle(processingHandle);
    	return 0;
    }
    



    C++ DX11

    • 已标记为答案 WillSu 2012年7月6日 3:27
    2012年7月5日 16:01

全部回复

  • then() 既已是在异步调用后的Completed中执行,如果你要在外面等待异步操作,你可以不使用then方法,仍旧使用AsyndOperation 来操作,判断其状态。

    	IAsyncOperation<StorageFile^>^ fileop= KnownFolders::DocumentsLibrary->GetFileAsync("test.txt");
    	fileop->Completed = ...;
    	while (fileop->Status != Windows::Foundation::AsyncStatus::Completed);


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 WillSu 2012年7月5日 7:07
    • 取消答案标记 WillSu 2012年7月5日 7:08
    2012年7月5日 5:41
    版主
  • 使用 while (fileop->Status != Windows::Foundation::AsyncStatus::Completed); 如何才能让他不锁死线程? 
    2012年7月5日 7:09
  • 不锁死那就是异步操作,这样不就和你问的问题矛盾了吗?

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年7月5日 15:08
    版主
  • 如果说你只要当异步执行完成通过callback回调返回或者执行下一步,那么你就把代码写入Completed委托,或者你AsTask().ContinueWith(Func(...))也行。不过这还是异步操作阿。

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年7月5日 15:09
    版主
  • 我的做法,不知好不好,也请版主指点。

    int CFileAgentWinRT::OpenAndReadTextFile( WCHAR* fileName,const WCHAR* &txt,UINT &size ,bool sync) // winrt UI thread always async
    {
    	// Create the event handle that will later signal when background processing has completed.
    	HANDLE processingHandle = CreateEventEx(
    		nullptr, // Default security attributes
    		nullptr, // Manual-reset event
    		false,   // Initial state is non-signaled
    		EVENT_ALL_ACCESS  // Allow other threads to interact with handle.
    		);
    	auto t=create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new String(fileName)))
    	.then([this](StorageFile^ file) {
    	return FileIO::ReadTextAsync(file);
    	},task_continuation_context::use_arbitrary())
    	.then([this,&txt,&size,processingHandle](task<String^> previousTask)
    	{
     		try
     		{
     			mReadText = previousTask.get();
     			txt = mReadText->Data();
     			size = mReadText->Length();
    			SetEvent(processingHandle);
     		}
     		catch (...)
     		{
    
     		}
     		return 1;
    	},task_continuation_context::use_arbitrary());
    
    	if (sync)
    		WaitForSingleObjectEx(processingHandle, 1000, false);
    	CloseHandle(processingHandle);
    	return 0;
    }
    



    C++ DX11

    • 已标记为答案 WillSu 2012年7月6日 3:27
    2012年7月5日 16:01
  • 感谢 Raptor ,你的做法很好用
    2012年7月6日 3:27