-7

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

编辑:我正在监视最后一次运行以及 15:00 和 :45 分别在 8 分钟内复制。:15 还没有结束,:30 也没有结束,而且都在 :45 之前至少 10 分钟开始。

这是我的代码:

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;
            }
        }
    }
}
4

2 回答 2

2

这里有些东西不太对劲。首先,您设置了 4 个计时器以并行运行。如果你考虑一下,那就没有必要了。您不需要 4 个线程一直并行运行。您只需要以特定的时间间隔启动任务。那么你需要多少个定时器?一。

第二个问题是为什么TimeSpan.FromMilliseconds(-1)?这样做的目的是什么?我不明白你为什么把它放在那里,但我不会。

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

这是我要做的:

  1. 将需要下载的文件存储在数组/List<> 中。难道你不能发现你每次都在做同样的事情吗?为什么要为此编写 4 个不同版本的代码?这是不必要的。将项目存储在数组中,然后只需更改调用中的索引!
  2. 以大约 5 秒的间隔设置计时器。当它达到 20 分钟/ 35 分钟/ 等标记时,生成一个新线程来执行任务。这样,即使前一个任务没有完成,新任务也可以开始。
  3. 等待所有线程完成(终止)。当他们这样做时,检查他们是否抛出异常,并在必要时处理它们/记录它们。
  4. 一切完成后,终止程序。

对于第 2 步,async如果您使用的是 .NET 4.5,则可以选择使用 new 关键字。但是如果您手动使用线程,它不会产生明显的差异。

为什么它这么慢......你为什么不使用任务管理器检查你的系统状态?CPU 是否很高并且正在运行,或者网络吞吐量是否被其他东西占用了?您可以从那里轻松地自己说出答案。

于 2014-05-16T20:25:13.487 回答
-2

问题是 sftp 客户端。

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

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

于 2014-05-20T14:03:33.050 回答