Are Resharper's close warnings correct?

I faced the following situation today

public async Task<Stream> GetApproveDocumentAsync<T>(Guid id, int revision, PdfLayoutType pdfLayoutType, string resourceFilePath, CadDrawingType cadDrawingType, int approvalWidth, int approvalHeight, Action<T> fillModelAction = null) where T : BaseApproveModel, new() {
    var previewFileName = $"{id}_{revision}_preview.png";
    Stream previewFile;
    using (var resourceFileStream = new FileStream(resourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)) {
        previewFile = await _cadApiService.ConvertDrawingToImageAsync(resourceFileStream, cadDrawingType, FileFormat.EVD, FileFormat.PNG, approvalWidth, approvalHeight).ConfigureAwait(false);
    }
    Func<string[], T> createBaseApproveModelFunc = graphicContentFilenames => { //Implicitly captured closure: previewFile
         var model = new T {
             GraphicContentFiles = graphicContentFilenames,
             CadPreview = previewFileName,
             Customer = _userService.GetCurrentOverrideCustomer()?.CustomerName
         };
         fillModelAction?.Invoke(model);
         return model;
    };
    Action<List<StreamWithFileName>> fillGraphicContentAction = currentGraphicContent => { //Implicitly captured closure: fillModelAction, this
        currentGraphicContent.Add(new StreamWithFileName {FileName = previewFileName, Stream = previewFile});
    };
    return await _apagoService.ConstcutPdf(pdfLayoutType, createBaseApproveModelFunc, fillGraphicContentAction).ConfigureAwait(false);
}

      

I thought I knew how closures work, but I can't figure out the behavior of ReSharper. Is ReSharper replacing these two warnings by mistake (or error)?

I am using ReSharper Ultimate 2016.2.2

+3


source to share


1 answer


I think what the resolver is saying is that these two closures also grab additional things that your code doesn't think it is using in this lambda. The first closure uses previewFileName

and this

(for the field _userService

), so your capture is clearly intentional, but: it may not be obvious to you that you are also capturing previewFile

. The reason that you capture extra things, is that the area for the captured cells is the same, so the compiler generates one closure to capture all the previewFile

, this

, previewFileName

and fillModelAction

- and a copy of the circuit has two methods - one for Func<string[], T>

and one for Action<List<StreamWithFileName>>

. note thatpreviewFileName

used by both lambdas, so: no warnings.



Understanding this can be important to the reasons for garbage collection - if one lambda lived much longer than the other, you might not want to accidentally save unnecessary things, hence the warning. For example, lambda fillGraphicContentAction

keeps everything this

alive (regardless of this

) even though lambda doesn't use this

.

+4


source







All Articles