The discrepancy between your C# implementation of the Welch's method and MATLAB's pwelch function when using a smaller window size (like hanning(512)) is likely due to differences in how the windowing is handled at the signal edges when segmenting the data; specifically, how MATLAB might be implicitly zero-padding the signal at the boundaries when calculating segments with a smaller window size than the segment length.