Task.Factory.StartNew忽略Task.WaitAll

时间:2016-07-16 17:37:28

标签: c# task

我在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);

2 个答案:

答案 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线程上,这可能会导致死锁。