Q:

Объединение файлов

Есть два файла file1.txt и file2.txt и на выходе мы должны получить file.txt
Использовал StreamReader и ReadLine, но скорость не очень. Дело в том, что файлы большие, оба порядка 20-80 мБ и их нужно не просто склеить, а разбить построчно и объединить каждую строку с каждой. Например, файл1 содержит строки вида
аа1
аа2 
аа3 
аа4

а файл2
bb1
bb2

В итоге мы хотим получить
aa1;bb1
aa1;bb2
aa2;bb1
aa2;bb2
...
aa4;bb2

Желательно еще сделать все с прогресс-баром, чтобы знать сколько еще ждать.
Спасибо.

A:

Вот вам простая версия без прогресс-бара:
var content2 = File.ReadAllLines("src2.txt");
File.WriteAllLines(
        "result.txt",
        File.ReadLines("src1.txt") // тут ReadLines, а не ReadAllLines
            .Select(l => l + ";")
            .SelectMany(prefix => content2.Select(l2 => prefix + l2)));

Для прогресс-бара надо UI, многопоточность и BackgroundWorker или лучше async/await, двумя строчками кода не обойдёшься.

A:

А что значит скорость не очень? Вы их каждый раз читаете? Раз уж @VladD уже предложил Linq-Fu ответ, предложу вариант с прогрессбаром:
class CartesianFiles : BackgroundWorker
{
    private readonly String filename1;
    private readonly String filename2;
    private readonly String outfile;

    public CartesianFiles(String f1, String f2, String outf) {
        // Передаем все исходные данные
        filename1 = f1;
        filename2 = f2;
        outfile = outf;

        // Разрещаем вызов ReportProgress
        WorkerReportsProgress = true;
    }

    protected override void OnDoWork(DoWorkEventArgs e) {

        var strings1 = File.ReadAllLines(filename1);
        var strings2 = File.ReadAllLines(filename2);

        // Каждый такой вызов обновляет состояние прогресса у всех подписчиков
        ReportProgress(0); 
        var i = 0;

        using (var outstrings = new StreamWriter(File.OpenWrite(outfile))) {

            foreach (var s1 in strings1) {

                foreach (var s2 in strings2) {
                    outstrings.Write(s1);
                    outstrings.Write(';');
                    outstrings.WriteLine(s2);
                }

                ReportProgress(strings1.Length * 100 / ++i);

            }
        }

        ReportProgress(100);
    }

}

public class Usage
{
    public void Start() {
        var worker = new CartesianFiles("in1.txt", "in2.txt", "out.txt");
        // Подписываемся на изменение прогресса фоновой работы
        worker.ProgressChanged += 
            delegate(object sender, ProgressChangedEventArgs args) { 
                  bpBar.Value = args.ProgressPercentage; // Обновляем прогрессбар
            }; 
        worker.RunWorkerAsync(); // Запускаем в фоне
    }
}

