2012-07-09 29 views
9

tôi đã xác định DataContract sau mà thực hiện IDisposable:Tại sao Vứt bỏ đang được gọi trên DataContract mặc dù dịch vụ vẫn đề cập đến nó?

[DataContract] 
public class RegularFileMetadata : FileMetadataBase, IDisposable 
{ 
    bool _Disposed = false; //note this! 

    //... 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!_Disposed) 
     { 
      //... 
      _Disposed = true; //note this too! 
     } 
    } 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 

Và tôi gọi phương thức dịch vụ sau đi qua một thể hiện của hợp đồng dữ liệu trên:

[OperationContract] 
[ServiceKnownType(typeof(RegularFileMetadata))] 
Guid BeginUpload(FileMetadataBase metadata); 

Trong việc thực hiện BeginUpload, tôi chỉ đơn giản lưu siêu dữ liệu vào từ điển là:

Dictionary<Guid, RegularFileMetadata> _Dict; 

public Guid BeginUpload(FileMetadataBase fileMetadata) 
{ 
    //... 
    var metadata = fileMetadata as RegularFileMetadata; 
    Guid sessionId = Guid.NewGuid(); 
    _Dict.Add(sessionId, metadata); //metadata SAVED! 
    return sessionId ; 
} 

Câu hỏi của tôi là ngay lập tức sau khi trở về từ phương pháp này, tại sao Dispose() được gọi mặc dù tôi đã lưu phiên bản trong từ điển _Dict?

Tôi đã xác minh rằng Dispose() phương pháp được gọi là trên cùng dụ mà tôi đã lưu trong từ điển của tôi, như _Disposed trở thành true cho lưu đối tượng, tức là _Dict[sessionId]._Disposed trở thành true!

Các hành vi phục vụ dịch vụ của tôi được thiết lập như:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
+0

Bạn có ssure rằng Dispose (..) được gọi trên ** cùng một trường hợp ** bạn đã tạo? Ý tôi là, * có thể * đã tạo ra một thể hiện khác của lớp và Dispose (..) được gọi là * đó * một. Kiểm tra * hashcode * của trường hợp bạn nhận được Dispose (..) trên ... – Tigran

+0

@Tigran: Có ... – Nawaz

+0

@Tigran: Tôi đã cập nhật câu hỏi của mình với: * "Tôi đã xác minh rằng phương thức Dispose() được gọi trên cùng một ví dụ mà tôi đã lưu trong từ điển của tôi, vì _Disposed trở thành sự thật cho đối tượng đã lưu. "* – Nawaz

Trả lời

14

Nó đang được xử lý bởi vì đó là đối tượng "thuộc" để WCF - nó tạo ra các trường hợp đối tượng ra khỏi không khí mỏng, để vượt qua như một tham số để bạn phương pháp. Và, nó là loại, đủ để quan sát rằng đối tượng này thực hiện IDisposable, do đó, nó xử lý nó một khi phương pháp của bạn hoàn thành.

Nếu bạn muốn một đối tượng của đối tượng này treo lên sau khi phương thức của bạn hoàn tất, thì bạn cần tự tạo một cá thể như vậy, sao chép các chi tiết liên quan từ thể hiện này sang thể hiện khác.

tại sao Dispose() được gọi là mặc dù tôi đã lưu dụ trong từ điển _Dict

Bởi vì mô hình Dispose để làm với tài liệu tham khảo và thu gom rác thải. Tất cả những gì quan trọng là, bất cứ khi nào các tham chiếu đến một đối tượng dùng một lần đang được truyền đi giữa nhiều phương thức/tác nhân/đại lý, có một thỏa thuận về "ai" có trách nhiệm gọi Dispose và khi nào. Trong trường hợp này, "người" là cơ sở hạ tầng WCF.


Correction - bạn có thể thay đổi hành vi này bằng cách thêm thuộc tính OperationBehavior phương pháp của bạn, và thiết lập AutoDisposeParameters false:

[OperationBehavior(AutoDisposeParameters=false)] 
public Guid BeginUpload(FileMetadataBase fileMetadata) 
{ 
    //... 
    var metadata = 
+0

+1. Có ý nghĩa. :-) – Nawaz

Các vấn đề liên quan