1

1 日に 1 回だけ実行される単純な 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メソッドはほとんど同じです。データベースでクエリを実行し、HTMLTextWriter を使用して HTML テーブルを作成し、テーブルを文字列として返します。

このコードは、マルチスレッドまたは async-await パターンを使用して改善できますか? 問題のコードは、StringBuilder オブジェクトに行を追加する場所です。

編集:これまでマルチスレッドを使用したことがないため、質問をしました。それが可能かどうかを知りたかっただけです。その上、プログラムは今では十分に速く実行されます。

4

3 に答える 3

2

生成するものが1つだけの場合、同期を考慮する必要があるため、並列化は複雑です。タスクの並列化(並列で実行される個別の分離された操作)を実行できる場合、並列化はより明白な候補です。また、複雑な作業が必要かどうかを判断するのに十分な情報を提供していません。

  • 今どれくらいかかりますか?
  • その時間がかかるのは問題ですか?

(多大な努力を正当化するために)重大な利益がある場合は、確かに!しかし、答えは「いいえ」であると強く思います。その場合は、そのままにしておいてください。1回の操作で複数のスレッドを処理するのは複雑です。

個別のドキュメントセクションを並列タスクと見なすことができますが、HTMLの生成は通常非常に高速です。したがって、これをプロファイリングして時間がかかることがわかっていない限り、気にしないでください。はるかに可能性が高い:データクエリがブロックされている。その場合、並列化について心配することなく、それを改善するために少し時間を費やしてください。

于 2011-10-22T11:39:57.687 に答える
1

メソッドが分離されている場合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;
...
于 2011-10-22T11:43:40.103 に答える
0
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); }
);
于 2011-10-22T11:40:23.517 に答える