0

私は、栄光のメールマージとPDFへのファイル変換に相当することを行っています... .Net 4.5に基づいて、スレッドを実行できる方法がいくつかあります。スレッド セーフ キューを使用するもの (プラン A) は興味深いようですが、潜在的な問題が見られます。どう思いますか?私はそれを短くしようとしますが、必要なものを入れます.

これは、PDF 変換よりもデータベース処理の方がはるかに時間がかかるという前提で機能します。

どちらの場合も、各ファイルのデータベース処理は独自のスレッド/タスクで実行されますが、PDF 変換は多数の単一スレッド/タスクで実行することも (プラン B)、単一の長時間実行スレッドで実行することもできます (プラン A)。 . 気になるのはそのPDF変換です。すべてが try/catch ステートメントにありますが、そのスレッドが失敗してはならず、すべてが失敗する (プラン A)。それは良い考えだと思いますか。任意の提案をいただければ幸いです。

/* A class to process a file: */ 
public class c_FileToConvert
{
    public string InFileName { get; set; }
    public int FileProcessingState { get; set; }
    public string ErrorMessage { get; set; }
    public List<string> listData = null;
    c_FileToConvert(string inFileName)
    {
        InFileName = inFileName;
        FileProcessingState = 0;
        ErrorMessage = ""; // yah, yah, yah - String.Empty
        listData = new List<string>();
    }   
    public void doDbProcessing()
    {
        // get the data from database and put strings in this.listData
        DAL.getDataForFile(this.InFileName, this.ErrorMessage); // static function
        if(this.ErrorMessage != "")
            this.FileProcessingState = -1; //fatal error
        else // Open file and append strings to it
        {  
            foreach(string s in this.listData}
                ...
            FileProcessingState = 1; // enum DB_WORK_COMPLETE ...
         }
    }   
    public void doPDFProcessing()
    {
        PDFConverter cPDFConverter = new PDFConverter();
        cPDFConverter.convertToPDF(InFileName, InFileName + ".PDF");
        FileProcessingState = 2; // enum PDF_WORK_COMPLETE ...
    }       
}

/*** These only for Plan A ***/
public ConcurrentQueue<c_FileToConvert> ConncurrentQueueFiles = new ConcurrentQueue<c_FileToConvert>(); 
public bool bProcessPDFs;   

public void doProcessing() // This is the main thread of the Windows Service 
{
    List<c_FileToConvert> listcFileToConvert = new List<c_FileToConvert>();

    /*** Only for Plan A ***/
    bProcessPDFs = true;
    Task task1 = new Task(new Action(startProcessingPDFs)); // Start it and forget it
    task1.Start();

    while(1 == 1)
    {
        List<string> listFileNamesToProcess = new List<string>();
        DAL.getFileNamesToProcessFromDb(listFileNamesToProcess);

        foreach(string s in listFileNamesToProcess)
        {
            c_FileToConvert cFileToConvert = new c_FileToConvert(s);
            listcFileToConvert.Add(cFileToConvert);
        }       

        foreach(c_FileToConvert c in listcFileToConvert)
            if(c.FileProcessingState == 0)
                Thread t = new Thread(new ParameterizedThreadStart(c.doDbProcessing));

        /** This is Plan A - throw it on single long running PDF processing thread **/
        foreach(c_FileToConvert c in listcFileToConvert)
            if(c.FileProcessingState == 1)
                ConncurrentQueueFiles.Enqueue(c);

        /*** This is Plan B - traditional thread for each file conversion ***/              
        foreach(c_FileToConvert c in listcFileToConvert)
            if(c.FileProcessingState == 1)
                Thread t = new Thread(new ParameterizedThreadStart(c.doPDFProcessing));

        int iCount = 0;
        for(int iCount = 0; iCount < c_FileToConvert.Count; iCount++;)
        {
            if((c.FileProcessingState == -1) || (c.FileProcessingState == 2))
            {
                DAL.updateProcessingState(c.FileProcessingState)
                listcFileToConvert.RemoveAt(iCount);
            }
        }
        sleep(1000);
    }
}   
public void startProcessingPDFs() /*** Only for Plan A ***/
{
    while (bProcessPDFs == true)
    {
        if (ConncurrentQueueFiles.IsEmpty == false)
        {
            try
            {
            c_FileToConvert cFileToConvert = null;
            if (ConncurrentQueueFiles.TryDequeue(out cFileToConvert) == true)
                cFileToConvert.doPDFProcessing();
            }
            catch(Exception e)
            {
                cFileToConvert.FileProcessingState = -1;
                cFileToConvert.ErrorMessage = e.message;
            }
        }
    }
}

プラン A は良い解決策のように思えますが、タスクが何らかの理由で失敗した場合はどうなるでしょうか? はい、PDF 変換は個々のスレッドで実行できますが、データベース処理用に予約したいと考えています。

これは私ができる最も単純なコードとしてテキストエディターで書いたので、何かがあるかもしれませんが、私はそのアイデアを理解したと思います.

4

1 に答える 1