使用LINQ获取1000

D-W*_*D-W -2 c# linq parallel-processing enumerable

好吧,我的linq技能不是很好,所以我试着做以下事情.

说我有6000条记录(电子邮件地址)我想添加前1000个添加到密件抄送,发送,下一个1000添加到密送,发送,取1000添加到密送,发送等....

我开始打字,

string[] files = System.IO.Directory.GetFiles(@"C:\Mail\ ", "*.csv");

Parallel.ForEach(files, currentFile =>
{
    string filename = currentFile;
    StreamReader reader = new StreamReader(filename);
    var emailList = new List<String>();
    while (reader.Peek() >= 0)
    {
        emailList.Add(reader.ReadLine());
    }
    \\Here is where I need to do the linq?
    IEnumerable<string> list = emailList

    var message = new System.Net.Mail.MailMessage();
    foreach (var s in list)
    {
        MailAddress mailAddress = new MailAddress(s);
        message.Bcc.Add(mailAddress);
    }

    message.Subject = txtSubject.Text;
    message.From = new System.Net.Mail.MailAddress(txtFrom.Text);
    message.Body = txtMessage.Text;
    message.IsBodyHtml = true;
    var smtp = new System.Net.Mail.SmtpClient();

    smtp.Send(message);
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 6

你似乎在寻找一种Batch方法.这是一个实现:

public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
    List<T> buffer = new List<T>(batchSize);

    foreach (T item in source)
    {
        buffer.Add(item);

        if (buffer.Count >= batchSize)
        {
            yield return buffer;
            buffer = new List<T>(batchSize);
        }
    }
    if (buffer.Count > 0)
    {
        yield return buffer;
    }
}
Run Code Online (Sandbox Code Playgroud)

你现在可以写:

foreach(var batch in emailList.Batch(1000))
{
    var message = CreateMessage();
    foreach(var email in batch)
    {
        message.Bcc.Add(email);
    }
    message.Send();
}
Run Code Online (Sandbox Code Playgroud)

另一方面StreamReader,您可以使用File.ReadLines来IEnumerable<string>表示文件中的行,而不是使用a 来读取文件的行.它甚至具有流式传输数据的附带好处,而不是首先将所有行都拉入内存.

  • @RGraham`ReadLines`流数据是的; 当枚举器要求它时,它会取出下一行,而不是前面的所有行.尽管使用了"StreamReader",OP的代码不会传输数据; 相反,它使用流阅读器将其全部拉入列表,从而防止流式传输数据. (2认同)