我在Task.Factory.StartNew和Task.WaitAll方面遇到了一些问题。任务确实按照应有的方式启动,但看起来它只是忽略了Task.WaitAll,因为在点击我的按钮后(这是代码所在的事件),MessageBox已经弹出。
// connect and login to FTP server
$ftp_server = "domain.com";
$ftp_conn = ftp_connect($ftp_server) or die("Could not connect to $ftp_server");
$login = ftp_login($ftp_conn, 'php@domain.com', 'password')or die ("Error Login");
$or = "/TestUpload.txt";
$dest = 'TestUpload.txt';
// upload file
ftp_put($ftp_conn, $dest, $or, FTP_ASCII) or die("Errore di upload!");
// close connection
ftp_close($ftp_conn);
答案 0 :(得分:2)
您只需在完成后将任务添加到列表中。任务完成后执行ContinueWith
。所以Task.WaitAll
正在等待一个空的任务列表。
所以你可以这样做:
Task task = Task.StartNew(() =>
{
// Some code
}).ContinueWith((t) =>
{
pbProgress.Value++;
}, TaskScheduler.FromCurrentSynchronizationContext());
tasks.Add(task);
答案 1 :(得分:0)
tasks
列表仅在线程通过StartNew
完成后才会获取添加到其中的项目。您遇到的问题是,在将项目添加到集合之前,您正在点击Task.WaitAll(tasks.ToArray());
。您需要在创建它们的线程中将项目添加到集合中,而不是在continue with,
var newTask = Task.Factory.StartNew(() =>
{
// Some code
});
tasks.Add(newTask);
newTask.ContinueWith((t) =>
{
pbProgress.Value++;
}, TaskScheduler.FromCurrentSynchronizationContext());
但是您的代码也存在其他问题。您永远不会将TaskSchedueller
传递给工厂,如果不这样做,您可以easily accidentally start your thread on the UI thread。此外,我假设此代码在UI线程上运行,您的Task.WaitAll
将阻止UI线程。如果其中一个StartNew
线程最终出现在UI线程上,这可能会导致死锁。