gpt4 book ai didi

如果它们之间没有 sleep ,c# Task 将无法工作

转载 作者:行者123 更新时间:2023-11-30 13:48:11 24 4
gpt4 key购买 nike

我在 C# 中使用 Task 在多线程中通过 FTP 发送文件。

这是我的函数(文件是一个字符串列表)

 Task<bool>[] result = new Task<bool>[file.Count];
int j = 0;
foreach (string f in file)
{
result[j] = new Task<bool>(() => ftp.UploadFtp(f, "C:\\Prova\\" + f + ".txt", j));
result[j].Start();
j++;

//System.Threading.Thread.Sleep(50);

}
Task.WaitAll(result, 10000);

以及上传文件的功能

public static bool UploadFtp(string uploadFileName, string localFileName, int i)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://127.0.0.1/" + uploadFileName + ".txt");
//settare il percorso per il file da uplodare
//FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://desk.txt.it/");
request.Method = WebRequestMethods.Ftp.UploadFile;

request.Credentials = new NetworkCredential("ftp_admin", "");
//request.Credentials = new NetworkCredential("avio", "avio_txt");
try
{
Console.WriteLine(uploadFileName);
Console.WriteLine(i);
StreamReader sourceStream = new StreamReader(localFileName);
byte[] fileContents = File.ReadAllBytes(localFileName);

sourceStream.Close();
request.ContentLength = fileContents.Length;

Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();

FtpWebResponse response = (FtpWebResponse)request.GetResponse();

//MessageBox.Show("Upload File Complete, status {0}", response.StatusDescription);

response.Close();
return true;
}
catch (Exception e)
{
return false;
}

}

以这种方式,程序总是尝试保存列表的最后一个文件,但如果我添加 Sleep(50),它会正确上传文件。似乎只有当我不使用 sleep 时,程序才会启动 4 个任务来做同样的工作(保存最后一个文件),但我不明白为什么,我也不知道如何解决这个问题。

有人可以帮助我吗?谢谢

最佳答案

看看你的代码:

int j = 0;
foreach (string f in file)
{
result[j] = new Task<bool>(() => ftp.UploadFtp(f, "C:\\Prova\\" + f + ".txt", j));
result[j].Start();
j++;
}

无论何时执行,lambda 表达式都会使用 j 的当前值。因此,如果任务 j 递增后开始,您将错过预期的值。

在 C# 4 中,f 也有同样的问题 - 但此问题已在 C# 5 中修复。请参阅 Eric Lippert 的博客文章 "Closing over the loop variable considered harmful"了解更多详情。

最小的修复是微不足道的:

int j = 0;
foreach (string f in file)
{
int copyJ = j;
string copyF = f;
result[j] = new Task<bool>(
() => ftp.UploadFtp(copyF, "C:\\Prova\\" + copyF + ".txt", copyJ));
result[j].Start();
j++;
}

现在 copyJcopyF 什么都不会改变 - 您将在循环的每次迭代中捕获一个单独的变量。在 C# 5 中,您不需要 copyF,只需使用 f 即可。

...但我还建议使用 Task.Factory.StartNew()(或 .NET 4.5 中的 Task.Run)或仅使用 并行.For.

关于如果它们之间没有 sleep ,c# Task 将无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13273929/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com