【问题标题】:how to modify this single thread into multithreading in c# .net [closed]如何在c#.net中将此单线程修改为多线程[关闭]
【发布时间】:2012-01-16 04:55:29
【问题描述】:

您好,我在 c#.net 中使用单线程,如果假设作业 A 在一个很长的过程中运行,直到作业 A 完成,否则我将向您解释它现在是如何工作的,除非作业 A 完成它不会去作业 B,但是在这里要求是所有的工作都应该被激活,但没有一个工作被打断,所以我该如何修改这个线程,任何人都可以尽快给出一些建议

protected override void OnStart(string[] args)
{
    strNowDate = DateTime.Now.ToLongTimeString();
    timerjob.Elapsed += new ElapsedEventHandler(CsvGenFromDatabase);
    timerjob.Interval = Convert.ToDouble(DueTime);
    timerjob.Enabled = true;
    eventLog1.WriteEntry("my service started");
}
protected override void OnStop()
{
    strNowDate = DateTime.Now.ToLongTimeString();
    eventLog1.WriteEntry("my service stopped");
}
private void CsvGenFromDatabase(object sender, EventArgs e)
{
    timerjob.stop();
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew)) // Transaction Scope Started  
    {
        Thread threadITD = new Thread(new ThreadStart(FileGenerationForITD));  // Thread Initialize for ITD
        Thread threadCTD = new Thread(new ThreadStart(FileGenerationForCTD));  // Thread Initialize for CTD
        Thread threadCID = new Thread(new ThreadStart(FileGenerationForCID));  // Thread Initialize for CID
        Thread threadFFM = new Thread(new ThreadStart(FileGenerationForFFM));  // Thread Initialize for FFM
        try      
        {                
            if ((threadITD == null) ||
                (threadITD.ThreadState == System.Threading.ThreadState.Stopped) ||
                (threadITD.ThreadState == System.Threading.ThreadState.Unstarted))
            {
                threadITD.Start();  // Thread Started for ITD
            }                  
            if ((threadCTD == null) ||
                (threadCTD.ThreadState == System.Threading.ThreadState.Stopped) ||
                (threadCTD.ThreadState == System.Threading.ThreadState.Unstarted))
            {
                threadCTD.Start(); // Thread Started for CTD
            }
            if ((threadCID == null) ||
                (threadCID.ThreadState == System.Threading.ThreadState.Stopped) ||
                (threadCID.ThreadState == System.Threading.ThreadState.Unstarted))
            {
                threadCID.Start(); // Thread Started for CID
            }                  
            if ((threadFFM == null) ||
                (threadFFM.ThreadState == System.Threading.ThreadState.Stopped) ||
                (threadFFM.ThreadState == System.Threading.ThreadState.Unstarted))
            {
                threadFFM.Start(); // Thread Started for FFM
            }
        }
        catch (Exception ex)
        {
            objErrorLog.SrtErrorText = ex.ToString().Substring(0, 25);
            objErrorLog.StrErrorDescription = ex.ToString();
            objErrorLog.WriteErrorLog(objErrorLog);
        }
        finally
        {
            scope.Complete();
        }
    }
    timerjob.start();
} 

【问题讨论】:

  • @MitchWheat - 只能这么说......
  • @M.Babcock 请帮我把它改成多线程,我是这个窗口服务的新手
  • @pravz - 虽然这只是您发布的代码的许多明显问题之一,但让我向您介绍BackgroundWorker
  • 你……似乎不明白你的代码在做什么。

标签: c# windows-services


【解决方案1】:

这似乎已经是多线程的。尝试在每个 FileGenerationForXXX 方法的开头和结尾添加日志记录代码,这样您就可以看到四个方法一起开始和分别停止。

private void FileGenerationForITD()
{
    eventlog1.WriteEntry("FileGenerationForITD started.");
    ...
    eventlog1.WriteEntry("FileGenerationForITD finished.");
}

此外,您可以删除所有 if 语句。线程对象保证处于该状态,因为newStart() 之间没有任何变化。

Thread threadITD = new Thread(new ThreadStart(FileGenerationForITD));
Thread threadCTD = new Thread(new ThreadStart(FileGenerationForCTD));
// ...
try
{
    ThreadITD.Start();
    ThreadCTD.Start();
    // ...
}

编辑:回应 cmets。

为了防止计时器在线程全部完成之前第二次触发,我建议在再次启动计时器之前加入线程。 Thread.Join() 导致该线程休眠,直到引用的线程结束。所有其他线程继续不间断。

private void CsvGenFromDatabase(object sender, EventArgs e)
{
    timerjob.stop();

    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        Thread threadITD = new Thread(new ThreadStart(FileGenerationForITD));
        Thread threadCTD = new Thread(new ThreadStart(FileGenerationForCTD));
        Thread threadCID = new Thread(new ThreadStart(FileGenerationForCID));
        Thread threadFFM = new Thread(new ThreadStart(FileGenerationForFFM));

        threadITD.Start();
        threadCTD.Start();
        threadCID.Start();
        threadFFM.Start();

        threadITD.Join();
        threadCTD.Join();
        threadCID.Join();
        threadFFM.Join();

        scope.Complete();
    }

    timerjob.start();  
}   

【讨论】:

  • 你能简单解释一下吗,但我正在检查线程何时为空或在这种情况下停止,只有我说启动线程
  • 只看一个线程,比如threadITD。首先,您声明了threadITD = new Thread(...),不久之后测试了threadITD == nullthreadITD 如何同时变为空?它不能,所以那个测试是没有意义的。其次,new Thread 具有默认的ThreadState = Unstarted。这怎么能改变?只能调用threadITD.Start()threadITD.Abort()。在您测试ThreadState 之前,这些都不会被调用,因此测试的结果是已知的。基本上,您的 if 语句测试有保证的已知条件,因此是多余的。
  • 因为与此同时,如果另一个实例启动,现有线程不应该受到干扰,所以我这样做了,在 threadITD==null 之前检查这种情况,好吧,如果我错了意味着我你会这样说,但我怀疑我是否按照你上面的回复进行更新,假设一个实例已经开始,但工作仍在等待中,平均时间是另一个实例由计时器事件启动,因此第一个实例会影响吗?
  • 如果定时器第二次触发,并且第一个线程没有完成,那么是的,它将启动四个新线程。因为您的线程被声明为局部变量,所以每次 CsvGenFromDatabase 方法退出时它们都会被“遗忘”。请参阅上面的编辑。
猜你喜欢
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多