这段代码可能存在瓶颈还是资源密集型?

时间:2014-05-16 20:07:45

标签: c# .net ssh sftp winscp-net

它的代码将以15分钟的间隔执行4个线程。我最后一次运行它,前15分钟被快速复制(6分钟内有20个文件),但第二次15分钟要慢得多。这是零星的,我想确定,如果有任何瓶颈,它与远程服务器的带宽限制。

编辑:我正在监视上次运行,并且每次在8分钟内复制15:00和:45。 :15还没有完成,也没有:30,两者都开始至少10分钟前:45。

这是我的代码:

static void Main(string[] args)
{

    Timer t0 = new Timer((s) =>
    {
        Class myClass0 = new Class();
        myClass0.DownloadFilesByPeriod(taskRunDateTime, 0, cts0.Token);
        Copy0Done.Set();
    }, null, TimeSpan.FromMinutes(20), TimeSpan.FromMilliseconds(-1));

    Timer t1 = new Timer((s) =>
    {
        Class myClass1 = new Class();
        myClass1.DownloadFilesByPeriod(taskRunDateTime, 1, cts1.Token);
        Copy1Done.Set();
    }, null, TimeSpan.FromMinutes(35), TimeSpan.FromMilliseconds(-1));

    Timer t2 = new Timer((s) =>
    {
        Class myClass2 = new Class();
        myClass2.DownloadFilesByPeriod(taskRunDateTime, 2, cts2.Token);
        Copy2Done.Set();
    }, null, TimeSpan.FromMinutes(50), TimeSpan.FromMilliseconds(-1));

    Timer t3 = new Timer((s) =>
    {
        Class myClass3 = new Class();
        myClass3.DownloadFilesByPeriod(taskRunDateTime, 3, cts3.Token);
        Copy3Done.Set();
    }, null, TimeSpan.FromMinutes(65), TimeSpan.FromMilliseconds(-1));

}

public struct FilesStruct
{
    public string RemoteFilePath;
    public string LocalFilePath;
}

Private void DownloadFilesByPeriod(DateTime TaskRunDateTime, int Period, Object obj)
{

    FilesStruct[] Array = GetAllFiles(TaskRunDateTime, Period);
    //Array has 20 files for the specific period.

    using (Session session = new Session())
    {
        // Connect
        session.Open(sessionOptions);
        TransferOperationResult transferResult;
        foreach (FilesStruct u in Array)
        {
            if (session.FileExists(u.RemoteFilePath)) //File exists remotely
            {
                if (!File.Exists(u.LocalFilePath)) //File does not exist locally
                {
                    transferResult = session.GetFiles(u.RemoteFilePath, u.LocalFilePath);
                    transferResult.Check();
                    foreach (TransferEventArgs transfer in transferResult.Transfers)
                    {
                        //Log that File has been transferred
                    }
                }
                else
                {
                    using (StreamWriter w = File.AppendText(Logger._LogName))
                    {
                        //Log that File exists locally
                    }
                }

            }
            else
            {
                using (StreamWriter w = File.AppendText(Logger._LogName))
                {
                    //Log that File exists remotely
                }
            }
            if (token.IsCancellationRequested)
            {
                break;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

这里的事情并不完全正确。首先,你要设置4个定时器来并行运行。如果你考虑一下,就没有必要了。您不需要始终并行运行4个线程。您只需要按特定时间间隔启动任务。那么你需要多少计时器? ONE。

第二个问题是为什么TimeSpan.FromMilliseconds(-1)?那是什么意思?我无法弄清楚你为什么把它放在那里,但我不会。

第三个问题,与多编程无关,但无论如何,我应该指出,每次都要创建Class的新实例,这是不必要的。如果在您的类中,您需要设置构造函数并且您的逻辑以某种顺序访问类的不同方法或字段,那将是必要的。在您的情况下,您要做的就是调用方法。因此,您每次都不需要课程的新实例。你只需要制作你称之为静态的方法。

以下是我要做的事情:

  1. 将您需要下载的文件存储在数组/列表<>中。你不能发现你每次都在做同样的事情吗?为什么要为此编写4个不同版本的代码?这是不必要的。将项目存储在数组中,然后只需更改通话中的索引!
  2. 以5秒的间隔设置计时器。当它达到20分钟/ 35分钟/等标记时,产生一个新线程来完成任务。这样,即使前一个任务没有完成,新任务也可以开始。
  3. 等待所有线程完成(终止)。当他们这样做时,检查他们是否抛出异常,并在必要时处理/记录它们。
  4. 完成所有操作后,终止程序。
  5. 对于第2步,如果您使用的是.NET 4.5,则可以选择使用新的async关键字。但如果你手动使用线程,它就不会产生显着的差异。

    为什么它这么慢......为什么不用任务管理器检查你的系统状态? CPU是高并运行还是由其他东西占用的网络吞吐量或什么?你可以从那里轻松地告诉答案。

答案 1 :(得分:-2)

问题是sftp客户端。

控制台应用程序的目的是遍历列表<>并下载文件。我尝试使用winscp,尽管它完成了这项工作,但速度很慢。我也测试了sharpSSH,它甚至比winscp慢。

我终于使用了ssh.net,至少在我的特定情况下,它比winscp和sharpssh快得多。我认为winscp的问题在于我完成后没有明显的断开连接方式。使用ssh.net,我可以在每次下载文件后连接/断开连接,这是我对winscp无法做到的。