生产环境下System.Threading.Task无法启动

3
我可以为您提供翻译帮助,以下是您需要翻译的内容:

我有一个 C# Windows 服务,用于执行各种任务。在我的本地系统上它运行得非常完美,但是当我在产品服务器上启动它时,它不能执行其中的一个特定任务。

这是我的服务结构:

public static void Execute()
{
        try
        {
            // .... some work ....
            foreach (DataRow dr in dt.Rows)
            {
                string cc = dr["ccode"].ToString();
                Task objTask = new Task(delegate { RequestForEachCustomer(cc); });
                objTask.Start();
            }
        }
        catch (Exception ex)
        {
            // Logging in DB + Text File
        }
 }

public static void RequestForEachCustomer(object cc)
{
    try
    {
        // .... some work ....
        foreach (DataRow dr in dt.Rows)
        {
            WriteLog("RequestForEachCustomer - Before Task");
            Task objTask = new Task(delegate { RequestProcessing(dr); });
            objTask.Start();
            WriteLog("RequestForEachCustomer - After Task");
        }
    }
    catch (Exception ex)
    {
        // Logging in DB + Text File
    }
}

public static void RequestProcessing(object dr)
{
    try
    {
        WriteLog("Inside RequestProcessing");
        // .... some work ....
    }
    catch (Exception ex)
    {
        // Logging in DB + Text File
    }
}

现在,在生产服务器上发生的情况是,它记录了RequestForEachCustomer中的最后一条记录,即"RequestForEachCustomer - After Task",但它没有记录来自RequestProcessing的条目,这意味着任务根本没有开始。在数据库或文本文件中没有任何异常。
Windows事件查看器中也没有记录任何事件。此外,服务仍在运行(如果我在数据库中插入另一条记录,则立即由服务处理,因此服务也没有卡住。只是似乎无法处理RequestProcessing任务。)
我对此感到困惑,如果有人能指出我犯的错误,那就太好了。哦,顺便说一下,我忘了提到这个服务几天前在服务器上完美地工作,而且仍然在我的本地电脑上正常工作。
编辑:
WriteLog:
public static void WriteErrorLog(string Message)
{
            StreamWriter sw = null;
            try
            {
                lock (locker)
                {    
                    sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\LogFile.txt", true);
                    sw.WriteLine(DateTime.Now.ToString() + ": " + Message);
                    sw.Flush();
                    sw.Close();
                }
            }
            catch (Exception excep)
            {
                try
                {
                    // .... Inserting ErrorLog in DB ....
                }
                catch
                {
                    throw excep;
                }
                throw excep;
            }
        }

我还在OnStop()中记录了一条信息,类似于“服务已停止”,每次停止服务时都会记录日志,因此问题不可能存在于WriteLog函数中。


2
从代码片段来看,它表明dt.Rows为空,因此没有日志。 - BugFinder
2
你开始了任务,但从未await它。这意味着除非你在委托内显式地捕获和记录异常(而你外部的广泛错误处理似乎暗示你不会这样做...),否则任务内抛出的任何异常都将无法被看到。实际的委托RequestProcessing是什么样子的? - Tomas Aschan
2
如果异常是在任务内部抛出的,那么您将不会得到这个异常。使用 objTask.ContinueWith(t => /* log t.Exception */, TaskContinuationOptions.OnlyOnFaulted) 来记录实际的异常信息。 - JanDotNet
@TomasLycken 我也是这么想的...try catch块应该处理异常并记录它。"数据库或文本文件中没有异常"意味着我无法确定我的代码是否生成了任何异常,因为我在数据库或文本文件中看不到任何日志。 - NewbieProgrammer
@jdweng 但是该服务在文本文件中写入所有其他条目都很好。我不认为这是权限问题。 - NewbieProgrammer
显示剩余9条评论
1个回答

0

我建议您按照MSDN示例重构代码。在您的代码中,让我感到困扰的是,您从未在任何地方等待任务完成。

以下示例启动10个任务,每个任务都传递一个索引作为状态对象。索引从2到5的任务会抛出异常。对WaitAll方法的调用将所有异常包装在AggregateException对象中,并将其传播到调用线程。

来源:Task.WaitAll方法(Task[])

示例中的这行可能很重要:

Task.WaitAll(tasks.ToArray());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接