可以使用多线程来改进这个代码
本文关键字:代码 多线程 可以使 | 更新日期: 2023-09-27 18:11:57
我有一个简单的Windows服务,每天只运行一次。它在数据库中执行一些查询,生成适当的html内容(表,div,…),并将其以电子邮件的形式发送给多个收件人。
电子邮件的正文是这样创建的:
private static string GenerateBody()
{
using (var stringWriter = new StringWriter())
using (var htmlWriter = new HtmlTextWriter(stringWriter))
{
htmlWriter.RenderBeginTag("html");
htmlWriter.RenderBeginTag(HtmlTextWriterTag.Head);
htmlWriter.WriteLine("<meta http-equiv='"Content-Type'" content='"text/html; charset=utf-8'" />");
htmlWriter.RenderEndTag();
htmlWriter.RenderBeginTag("body");
htmlWriter.Write(
new StringBuilder()
.Append(OverviewParagraph.GenerateHTMLContent())
.Append(PackageWeightParagraph.GenerateHTMLContent())
.Append(BoxWeightParagraph.GenerateHTMLContent())
.Append(CodeQualityParagraph.GenerateHTMLContent())
.Append(ChecksParagraph.GenerateHTMLContent())
.ToString()
);
htmlWriter.RenderEndTag();
htmlWriter.RenderEndTag();
return stringWriter.ToString();
}
}
所有的GenerateHTMLContent
方法几乎相同-他们在我的数据库中执行查询,在htmltextwwriter的帮助下建立一个HTML表,并将表作为字符串返回。
这段代码可以改进与使用多线程或也许async-await模式?问题代码是我向StringBuilder对象追加行。
编辑:我问这个问题是因为我以前从未使用过多线程,只是想知道它是否可能。
如果它只生成一个东西,那么并行化是复杂的,因为您需要考虑同步。当您可以执行任务并行化(并行完成的单独和孤立的操作)时,并行化是一个更明显的候选。您也没有提供足够的信息来说明是否需要进行复杂的工作:
- 现在需要多长时间?
- 花那么多时间有问题吗?
如果有显著的收益(证明显著的努力是合理的),那么当然!然而,我强烈怀疑,答案是"不",在这种情况下,别管它了。在一个操作上处理多个线程是很复杂的。
您也许可以将单独的文档部分视为并行任务,但是HTML生成通常非常快—所以除非您对此进行了分析并且知道它们需要时间,否则不要麻烦。更有可能的是:你的数据查询是障碍。在这种情况下,花一些时间来改进它,而不用担心并行化。
如果GenerateHTMLContent
方法是隔离的(即如果并发运行它们不会相互干扰),您可以将它们一起启动,并在它们可用时收集结果:
// start tasks
Task<string> overviewParagraph =
Task.Factory.StartNew( () => OverviewParagraph.GenerateHTMLContent() );
Task<string> packageWeightParagraph =
Task.Factory.StartNew( () => PackageWeightParagraph.GenerateHTMLContent() );
....
// collect results
string overviewParagraphHtml = overviewParagraph.Result;
string packageWeightParagraphHtml = packageWeightParagraph.Result;
...
StringBuilder sb = new StringBuilder();
Parallel.Invoke(
() => { var s = OverviewParagraph.GenerateHTMLContent(); lock (sb) sb.Append(s); },
() => { var s = PackageWeightParagraph.GenerateHTMLContent(); lock (sb) sb.Append(s); },
() => { var s = BoxWeightParagraph.GenerateHTMLContent(); lock (sb) sb.Append(s); },
() => { var s = CodeQualityParagraph.GenerateHTMLContent(); lock (sb) sb.Append(s); },
() => { var s = CodeQualityParagraph.GenerateHTMLContent(); lock (sb) sb.Append(s); }
);