하나의 태스크가 변수에 할당하고 다음 태스크가 해당 변수에서 읽는 람다 식을 사용하는 연속 체인이 있습니다. Microsoft suggests using a shared_ptr
to wrap the variable even when the variable is a reference-counted handle (^). 람다 식으로 값으로 캡처 할 때 참조 카운트 핸들이 참조 카운트를 증가시키지 않습니까? 그렇다면 왜 shared_ptr
과 함께 참조 계산 핸들을 래핑 할 필요가 있습니까?연속 체인에서 공유 포인터가 필요합니까?
0
A
답변
3
문서는 만드는 분명히 연속 체인 에서
하나의 작업 변수에 할당하고, 다른 작업 읽기 그들이 어디에 대해 우려하고있는 경우가 그들이다 것을 그 변수
(강조는 광산입니다.) 이것은 객체 의 생애이 아니라 객체 신분의 질문입니다.
decoder
변수에 세심한주의를 기울이고 상기 Hilo project에서 예를 타고이다 (이는 shared_ptr<BitmapDecoder^>
)
decoder
변수 우선, 연속 요청의 외부 정의
task<InMemoryRandomAccessStream^> ThumbnailGenerator::CreateThumbnailFromPictureFileAsync(
StorageFile^ sourceFile,
unsigned int thumbSize)
{
(void)thumbSize; // Unused parameter
auto decoder = make_shared<BitmapDecoder^>(nullptr);
auto pixelProvider = make_shared<PixelDataProvider^>(nullptr);
auto resizedImageStream = ref new InMemoryRandomAccessStream();
auto createThumbnail = create_task(
sourceFile->GetThumbnailAsync(
ThumbnailMode::PicturesView,
ThumbnailSize));
return createThumbnail.then([](StorageItemThumbnail^ thumbnail)
{
IRandomAccessStream^ imageFileStream =
static_cast<IRandomAccessStream^>(thumbnail);
return BitmapDecoder::CreateAsync(imageFileStream);
}).then([decoder](BitmapDecoder^ createdDecoder)
{
(*decoder) = createdDecoder;
return createdDecoder->GetPixelDataAsync(
BitmapPixelFormat::Rgba8,
BitmapAlphaMode::Straight,
ref new BitmapTransform(),
ExifOrientationMode::IgnoreExifOrientation,
ColorManagementMode::ColorManageToSRgb);
}).then([pixelProvider, resizedImageStream](PixelDataProvider^ provider)
{
(*pixelProvider) = provider;
return BitmapEncoder::CreateAsync(
BitmapEncoder::JpegEncoderId,
resizedImageStream);
}).then([pixelProvider, decoder](BitmapEncoder^ createdEncoder)
{
createdEncoder->SetPixelData(BitmapPixelFormat::Rgba8,
BitmapAlphaMode::Straight,
(*decoder)->PixelWidth,
(*decoder)->PixelHeight,
(*decoder)->DpiX,
(*decoder)->DpiY,
(*pixelProvider)->DetachPixelData());
return createdEncoder->FlushAsync();
}).then([resizedImageStream]
{
resizedImageStream->Seek(0);
return resizedImageStream;
});
}
. 이 시점에서 값은 null입니다. 그것은 두 번째 연속 내에서 획득되고 설정되며, 그 객체의 속성 (PixelWidth
등)이 네 번째 연속 내에서 사용됩니다.
decoder
가
BitmapDecoder^
로 정의 할 수 있습니다
nullptr
로 설정 한 다음 그것을 두 번째 지속 내의 값을 할당 할 수 있었 (람다는 본질적으로 메모리 주소 0x00000000을 복사하는 핸들 복사본을 만들었습니다.)
원래 버전 (및 후속 참조)을 업데이트하려면 추가 간접 참조 (예 : BitmapDecoder^*
)가 필요합니다. shared_ptr<BitmapDecoder^>
은 그러한 간접 참조 중 하나이며, 원시 포인터와 달리 포인터의 수명을 관리 할 필요가 없다는 점에서 유용한 것입니다. 따라서 문서에서 권장됩니다.
예를 들어 TextBlock^
을 내 속편 외부에 만들고 첫 번째 연속에서 일부 속성을 설정하고 후속 연속에서 다른 속성을 읽는 경우와 같이 Object^
을 캡처하는 것으로 충분할 수도 있습니다. 이 경우 모든 핸들이 동일한 기본 오브젝트를 참조하며 연속은 오브젝트 자체의 ID를 겹쳐 쓰려고 시도하지 않습니다. (그러나 처음에 언급했듯이 이것은 문서가 참조하고있는 사용 사례는 아닙니다.)