2012-03-01 4 views
4

ImageList 개체를 처리하는 적절한 방법은 무엇입니까?ImageList 처분

일부 클래스에 private ImageList imageList 회원이 있다고 가정 해 보겠습니다. 자, 어떤 순간에 나는 다음과 같은 코드를 수행 : 같은 클래스에서

// Basically, lazy initialization. 
if (imageList == null) 
{ 
    imageList = new ImageList(); 
    Image[] images = Provider.CreateImages(...); 
    foreach (var image in images) 
    { 
     // Does the 'ImageList' perform implicit copying here 
     // or does it aggregate a reference? 
     imageList.Images.Add(image); 

     // Do I need to do this? 
     //image.Dispose(); 
    } 
} 

return imageList; 

을 내가 가지고있는 다음과 같은 방법으로 수행되는 Dispose 방법의 구현 :

public void Dispose() 
{ 
    if (!disposed) 
    { 
     // Is this enough? 
     if (imageList != null) 
      imageList.Dispose(); 

     disposed = true; 
    } 
} 

내가 거기에 확신을 이 코드의 일부 잠재적 인 문제가 있으므로 올바른 수정을 도와주십시오.

+0

관련 ([의 ImageList 원 화상을 배치하는 것은 목록으로부터 삭제] http://stackoverflow.com/questions/17639237/imagelist-disposing-the-original-image-removes-it-from- the-list). [ImageList의 원본 항목] 필드에있는 [참조 소스]의 주석 (https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ImageList.cs,75) 읽을 가치가 있습니다. – jrh

답변

4

예, 복사본을 만듭니다. 아래 CreateBitMap 호출을 유의하십시오. 따라서 자원 사용을 가능한 한 낮게 유지하려면 처리 라인의 주석을 제거해야합니다.

private int Add(ImageList.Original original, ImageList.ImageCollection.ImageInfo imageInfo) 
    { 
    if (original == null || original.image == null) 
     throw new ArgumentNullException("value"); 
    int num = -1; 
    if (original.image is Bitmap) 
    { 
     if (this.owner.originals != null) 
     num = this.owner.originals.Add((object) original); 
     if (this.owner.HandleCreated) 
     { 
     bool ownsBitmap = false; 
     Bitmap bitmap = this.owner.CreateBitmap(original, out ownsBitmap); 
     num = this.owner.AddToHandle(original, bitmap); 
     if (ownsBitmap) 
      bitmap.Dispose(); 
     } 
    } 
    else 
    { 
     if (!(original.image is Icon)) 
     throw new ArgumentException(System.Windows.Forms.SR.GetString("ImageListBitmap")); 
     if (this.owner.originals != null) 
     num = this.owner.originals.Add((object) original); 
     if (this.owner.HandleCreated) 
     num = this.owner.AddIconToHandle(original, (Icon) original.image); 
    } 
    if ((original.options & ImageList.OriginalOptions.ImageStrip) != ImageList.OriginalOptions.Default) 
    { 
     for (int index = 0; index < original.nImages; ++index) 
     this.imageInfoCollection.Add((object) new ImageList.ImageCollection.ImageInfo()); 
    } 
    else 
    { 
     if (imageInfo == null) 
     imageInfo = new ImageList.ImageCollection.ImageInfo(); 
     this.imageInfoCollection.Add((object) imageInfo); 
    } 
    if (!this.owner.inAddRange) 
     this.owner.OnChangeHandle(new EventArgs()); 
    return num; 
    } 

ImageList가 삭제되면 모든 이미지의 사본이 삭제됩니다. 다시 말하지만, 예, 양식을 닫을 때 처분하는 것은 다른 처분 선을 주석 처리하는 것 이외에 옳은 일입니다.

protected override void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
    if (this.originals != null) 
    { 
     foreach (ImageList.Original original in (IEnumerable) this.originals) 
     { 
     if ((original.options & ImageList.OriginalOptions.OwnsImage) != ImageList.OriginalOptions.Default) 
      ((IDisposable) original.image).Dispose(); 
     } 
    } 
    this.DestroyHandle(); 
    } 
    base.Dispose(disposing); 
} 
1

ImageList는 원본 이미지에 대한 참조를 소유하고 있지 않습니다. ImageList를 추가하면 이미지가 복사됩니다. 편리하게 원본을 처분 할 수 있습니다.
그러나 Dispose()에서 imageList.Images.Clear();으로 전화해야합니다.