An iterator might be perfect for this type of work:
public static IEnumerable<int> LoadFileWithProgress(string filename, StringBuilder stringData)
{
const int charBufferSize = 4096;
using (FileStream fs = File.OpenRead(filename))
{
using (BinaryReader br = new BinaryReader(fs))
{
long length = fs.Length;
int numberOfChunks = Convert.ToInt32((length / charBufferSize)) + 1;
double iter = 100 / Convert.ToDouble(numberOfChunks);
double currentIter = 0;
yield return Convert.ToInt32(currentIter);
while (true)
{
char[] buffer = br.ReadChars(charBufferSize);
if (buffer.Length == 0) break;
stringData.Append(buffer);
currentIter += iter;
yield return Convert.ToInt32(currentIter);
}
}
}
}
You can call it using the following:
string filename = "C:\\myfile.txt";
StringBuilder sb = new StringBuilder();
foreach (int progress in LoadFileWithProgress(filename, sb))
{
// Update your progress counter here!
}
string fileData = sb.ToString();
As the file is loaded, the iterator will return the progress number from 0 to 100, which you can use to update your progress bar. Once the loop has finished, the StringBuilder will contain the contents of the text file.
Also, because you want text, we can just use BinaryReader to read in characters, which will ensure that your buffers line up correctly when reading any multi-byte characters (UTF-8, UTF-16, etc.).
This is all done without using background tasks, threads, or complex custom state machines.