Как лучше всего управлять несколькими потоками в цикле в C # - PullRequest
0 голосов
/ 17 июля 2011

Я просматриваю список фильмов в порядке жанра и пытаюсь создавать и записывать в файлы, как я это делаю.Я хочу создать файл, записать в него связку, затем закрыть его при переходе к следующему жанру и создать новый файл.

Сейчас я получаю "Использование неназначенной локальной переменной 'GenStream'«когда я пытаюсь закрыть поток.Однако, если я закомментирую это и не закрою поток, я получу ту же ошибку в моем утверждении ELSE.Я не понимаю, почему я получаю эти ошибки, и был бы признателен за помощь в их устранении.Я отметил, где я получаю ошибки в коде ниже.

/// <summary>
/// Creates a file for each Genre, and writes movie info to each for the cooresponding movies
/// </summary>
/// <param name="cPath">Path to create HTML files in</param>
/// <param name="mList">List of Movies to generate Genre and Movie info from</param>
public static void WriteGenreHTML(string cPath, List<Movie> mList)
{
    int lineID = 0;
    string tmpGen = null;
    string strHeader, strMovie, strGenre, tmpGenre = null;
    StreamWriter genStream;

    // Gets a list of unique Genres from the MovieList
    var distinctGenres = from m in mList
                         from genre in m.Genres
                         group genre by genre into genres
                         select genres.First();

    // Gets a list of Movies with the associated Genres
    var moviesWithGenre = from g in distinctGenres
                          from m in mList
                          where m.Genres.Contains(g)
                          orderby g, m.Title
                          select new { Genre = g, Movie = m };

    // Traverses list of movies creating new HTML Genre files, and writing movie info to the HTML genre files
    foreach (var m in moviesWithGenre)
    {
        // Creates new HTML file if new Genre is detected
        if (m.Genre != tmpGen)
        {
            tmpGen = m.Genre;

            // Closes previously open Stream
            genStream.Close(); // ERROR: "Use of unassigned local variable 'genStream'

            // initiates streamwriter for catalog output file
            FileStream fs = new FileStream(cPath + Path.DirectorySeparatorChar + m.Genre, FileMode.Create);

            genStream = new StreamWriter(fs);

            // Generates header info for new file, and new Genre
            strHeader = "<style type=\"text/css\">\r\n" + "<!--\r\n" + "tr#odd {\r\n" + "   background-color:#e2e2e2;\r\n" + "  vertical-align:top;\r\n" + "}\r\n" + "\r\n" + "tr#even {\r\n" + "   vertical-align:top;\r\n" + "}\r\n" + "div#title {\r\n" + "  font-size:16px;\r\n" + "    font-weight:bold;\r\n" + "}\r\n" + "\r\n" + "div#mpaa {\r\n" + "    font-size:10px;\r\n" + "}\r\n" + "\r\n" + "div#genre {\r\n" + " font-size:12px;\r\n" + "    font-style:italic;\r\n" + "}\r\n" + "\r\n" + "div#plot {\r\n" + "   height: 63px;\r\n" + "  font-size:12px;\r\n" + "    overflow:hidden;\r\n" + "}\r\n" + "\r\n" + "div#genre_heading {\r\n" + "    height: 50px;\r\n" + "  font-size: 24px;\r\n" + "   font-weight: bold;\r\n" + " text-align: center;\r\n" + "    text-decoration: underline;\r\n" + "}\r\n" + "-->\r\n" + "</style>\r\n" + "\r\n" + "<html>\r\n" + " <body>\r\n" + "     <table>\r\n";
            strHeader += "          <tr>\r\n" + "               <td colspan=2>\r\n" + "                 <div id=\"genre_heading\">" + m.Genre + "</div>\r\n" + "                </td>\r\n" + "          </tr>\r\n" + "\r\n";

            // Writes header HTML to stream
            genStream.WriteLine(strHeader);

            Console.WriteLine();
            Console.WriteLine("Now Processing " + m.Genre);
        }
        // Otherwise creates and writes HTML code for the Movie
        else
        {
            // Creates string of links to the Genre HTML pages
            foreach (string genre in m.Movie.Genres)
                tmpGenre += ", <a href=\"" + genre + ".html\" target=\"_blank\">" + genre + "</a>";
            strGenre = tmpGenre != null ? tmpGenre.Substring(2) : null;

            // Generates the HTML for the Movie
            strMovie = lineID == 0 ? "          <tr id=\"odd\" style=\"page-break-inside:avoid\">\r\n" : "          <tr id=\"even\" style=\"page-break-inside:avoid\">\r\n";
            strMovie += "               <td>\r\n" + "                   <img src=\".\\images\\" + m.Movie.ImageFile + "\" width=\"75\" height=\"110\">\r\n" + "             </td>\r\n" + "              <td>\r\n" + "                   <div id=\"title\">" + m.Movie.Title + "</div>\r\n" + "                  <div id=\"mpaa\">" + m.Movie.Certification + " " + m.Movie.MPAA + "</div>\r\n" + "                  <div id=\"genre\">" + strGenre + "</div>\r\n" + "                   <div id=\"plot\">" + m.Movie.Plot + "</div>\r\n" + "                </td>\r\n" + "          </tr>\r\n";

            // Writes the HTML to the stream
            genStream.WriteLine(strMovie); // ERROR: "Use of unassigned local variable 'genStream'
            lineID = lineID == 0 ? 1 : 0;
        }
    }

    string closingHTML = "      </table>\r\n" + "   </body>\r\n" + "</html>";
    genStream.WriteLine(closingHTML);
    genStream.Close();
}

Ответы [ 3 ]

2 голосов
/ 17 июля 2011

Вы можете использовать приведенный ниже код для проверки того, что поток уже инициализирован или нет

Если поток инициализирован, вы можете закрыть его

if (genStream == null )
{
genStream.Close()
}

Надеюсь, это будет работать для вас..

1 голос
/ 17 июля 2011

Причина, по которой вы получаете ошибку «Использовать неназначенную локальную переменную GenStream», заключается в том, что вы объявили ее, когда вызываете genStream.Close () в блоке if, ему ничего не назначено просто декларация (воспринимайте ее как заполнитель).

Когда вы комментируете genStream.Close (), вы снова получаете ошибку в своем блоке else, потому что (с точки зрения области видимости блока else) ей снова ничего не было назначено.

Вот пример того, что я предлагал в своем последнем комментарии к вашему предыдущему сообщению:

foreach (var g in DistinctGenres)
{
    FileStream fs = new FileStream(cPath + Path.DirectorySeparatorChar + g.Genre, FileMode.Create);
    StreamWriter genStream = new StreamWriter(fs);

    // Write your header here

    foreach (var m in Genres)
    {
        // Generates the HTML for the Movie

        // Writes the HTML to the stream
        genStream.WriteLine(strMovie);
        lineID = lineID == 0 ? 1 : 0;

    }

    string closingHTML = "      </table>\r\n" + "   </body>\r\n" + "</html>";
    genStream.WriteLine(closingHTML);
    genStream.Close();
}

Это устраняет необходимость проверки if и, как правило, упрощает то, что вы пытаетесь выполнить, ИМО.

Возможно, вам придется скорректировать два запроса или оставить первый запрос и выполнить второй запрос в зависимости от текущего жанра, для которого вы создаете веб-страницу.

Еще одна мысль - переместите второй запрос внутрь первого цикла foreach, назначьте текущий жанр переменной и настройте второй запрос следующим образом:

var moviesWithGenre = from g in distinctGenres
                      from m in mList
                      where m.Genres.Contains(currentGenre) // currentGenre is assigned a value in the first (outer) foreach loop
                      orderby g, m.Title
                      select new { Genre = g, Movie = m };
1 голос
/ 17 июля 2011

Может быть, вы также можете добавить, помимо ответов здесь, использование ключевого слова "using", поскольку оно будет вставлено в окончательную нотацию IL try / finally, которая обеспечит закрытие вашего потока даже в случае возникновения исключительной ситуации. Короче говоря, псевдокод может выглядеть примерно так:

с использованием (StreamWriter genStream = new StreamWriter (...)) {

   //use stream here

   genStream.Close();

} // распоряжение genStream будет вызываться автоматически при выходе из режима «using».

Надеюсь, это поможет.

Привет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...