0

我正在开发一个基于 .Net 4.0 C# Windows 服务(类似 Dropbox)的应用程序,该应用程序连续运行并监视特定文件夹的内容和更新,并通知数据库的更改,类似的客户端应用程序也将安装在其他机器上它将对其主机中的同一文件夹执行适当的更新。我已经开发了具有多个线程和递归调用的整个应用程序,它们将继续执行并通知更改。应用程序在 3 小时后运行良好 3 小时,它引发堆栈溢出异常并崩溃。

更具体地说,我有 9 个线程,其中一些线程执行以下工作

1) threadFSWToDB - 将任何文件更改(添加、重命名、删除)写入 DB。

2) threadDBToUploadLogList - 在服务器上创建一个文件夹,其他客户端将从那里下载文件。

3) threadDoUpload - 将文件上传到网络服务器。

4) threadDBToDownloadList - 将通过轮询数据库上传要执行的更改列表。

我的问题是,这是可行的解决方案还是我需要重新考虑整个应用程序的设计。如果是,那么执行上述任务(顺序或并行)的最佳方式是什么。什么是执行像这样的永无止境和连续的任务的最基本方法。

我的代码如下,我不知道要放多少才能把事情弄清楚

Thread threadFSWToDB = new Thread(() => WriteFSWLogListToDatabase());


private static void WriteFSWLogListToDatabase()
    {
        try
        {
            using (var objEntities = new ShareBoxEntities()) // EF class instantiation
            {
// this DB class constructor call later on throws stack overflow exception not necessarily from this method
                var objConnector = new DBConnector(objEntities); 
                var objConnector = new DBConnector();
                List<string> directories = objConnector.GetAllSharedDirectoryRelativePaths();
                if (FSWLogList != null && FSWLogList.Count() > 0)
                {
                    for (int i = 0; i <= FSWLogList.Count - 1; i++)
                    {

            // some file changes being written to Database
                            FSWLogList[i].SavedInDB = true;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
    // write to event log and mail to administrator
        }
        finally
        {
            if (FSWLogList != null && FSWLogList.Count > 0)
            {
                FSWLogList.RemoveAll(item => item.SavedInDB == true);
            }
            Thread.Sleep(5000);
            WriteFSWLogListToDatabase();
        }
    }

如果递归是主要原因,那么为什么应用程序在一两天内运行良好,然后开始表现出上述行为

4

3 回答 3

0

不知道细节很难说,但是堆栈溢出错误通常意味着您对递归的深入了解

简单的例子

public void ThrowStackOverflow()
{
    ThrowStackOverflow()
}

总是会抛出堆栈溢出,因为递归没有出口。调用堆栈越来越深,直到没有空间。

我怀疑您的程序存在类似的自我参照主义问题。

如果你有一个递归调用,在结束之前可能会变得太深,你就有堆栈溢出的风险。

或者,如果您的线程在没有终止的情况下创建自己,或者即使您只是继续创建新线程而没有清理它们,那么某些东西将不可避免地出现。

于 2012-09-12T17:41:13.000 回答
0

感谢大家宝贵的时间。

我找到了解决我的问题的方法,递归函数调用已被替换为while(true) //loop 仍在各自的线程上被调用 这确保了我的监视文件夹的函数在 a try and catch 确保即使在异常发生后它也会继续。我在使用while(true)时遇到的问题是函数中使用的任何资源都可用于在单独线程上运行的其他函数,这是通过在特定时期调用 thread.sleep 来处理的。它可能不是针对类似问题的通用解决方案,但它符合我的要求,因此我希望其他人在类似情况下实施所述解决方案之前要小心。

于 2012-10-09T12:04:48.290 回答
0

对我来说听起来你很高兴。对于数据库,您有 BeginExecuteNonQuery 用于没有线程的异步数据库。要从数据库获取通知,您有查询通知。对于文件,您有 FileSystemWatcher。我只会使用 BackGroundWorker 来上传和下载文件。如果您要上传/下载到一台服务器,那么并行执行文件将无济于事,因为您很可能受到带宽的限制。

于 2012-09-12T21:16:40.350 回答