提前感谢您的时间和帮助。
我正在使用 WPF 应用程序中的 TPL 从远程服务器下载文件。我有一个在 UI 线程上运行的“传输管理器”方法,我从中创建后台任务以单独下载文件。我在后台任务上附加了继续任务以更新 UI。
问题是:对于第一个文件,下载任务按预期在新线程上开始。但对于所有后续下载,它使用与锁定应用程序的 UI 相同的线程。
我已经完成了我的作业,阅读了相关材料,因此我无法理解这种行为,确定我做错了什么以及如何解决它。任何帮助,提示,指针,解释表示赞赏。谢谢。
我正在从调试模式附加示例代码和输出窗口文本。
private void btnNew_Click(object sender, RoutedEventArgs e)
{
// do some work and prepare transfer state object(my custom object)
...
..
iTaskFactory = new TaskFactory
(TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.None);
// call transfer manager
this.ManageTransfer(null, iDownloadState);
}
private void ManageTransfer(Task antecedent, TransferState ts)
{
if(antecedent == null)
// this is the first invocation of the task from GetNew / Upload methods
{
ts.IsActive = true;
// some code....
}
else if(antecedent.IsFaulted) // check exception on previous task executed
// if there is a fault, then retry the page again
{
// do some error logging....
//retry transferring the same page again
pageToTranfer = ts.PagesTransferred + 1;
}
else
// if the page was successfully transferred
{
//increment transfer count
ts.PagesTransferred += 1;
// update UI.... (as running on UI Thread)
// if all pages are transferred, then exit method. No further tasks to queue
if(ts.PagesTransferred == ts.Pages)
{
return;
}
pageToTranfer = ts.PagesTransferred + 1;
}
Task transferTask; // should run in background thread
// **Problem is that afer first execution**,
// **this also runs on UI Thread!!**
Task continuationTask; // should run in UI thread
localFile = "someName.txt"; //..... work out next file to transfer
serverFile = "someName.txt"; //..... work out next file to transfer
time = DateTime.Now.ToString("hh:mm:ss.ffff"); //.ToShortTimeString();
Debug.WriteLine(time + "starting download :" + pageToTranfer.ToString()
+ " This is Thread: "
+ Thread.CurrentThread.ManagedThreadId.ToString());
transferTask = iTaskFactory.StartNew(() => Download(serverFile, localFile));
continuationTask = transferTask.ContinueWith((t1Task) => ManageTransfer(t1Task, ts)
, TaskScheduler.FromCurrentSynchronizationContext());
}
public bool Download(string aCloudPath, string aLocalPath)
{
time = DateTime.Now.ToString("hh:mm:ss.ffff"); //.ToShortTimeString();
Debug.WriteLine(time + " in background for downloading "
+ aCloudPath + " using thread:"
+ Thread.CurrentThread.ManagedThreadId.ToString());
// code to transfer file... no access to UI or any shared variable
return true;
}
输出窗口:
10:37:53.2629 开始下载:1 这是线程:8
10:37:55.2720 在后台使用线程:15 下载 file-01.txt
10:37:56.4120 开始下载:2 这是线程:8
10:38:00.4143 在后台使用线程:8 下载 file-02.txt
10:38:01.2413 开始下载:3 这是线程:8
10:38:05.2445 在后台使用线程:8 下载 file-03.txt
10:38:05.8606 开始下载:4 这是线程:8
10:38:09.8618 在后台使用线程:8 下载 file-04.txt
如您所见,第一次下载功能按预期在后台运行。但之后它继续在 UI 线程中运行! 我期望 ManagerTranfer 在同一个线程中运行,而另一个线程用于下载功能。
我也用简单的任务(即没有TaskFactory)尝试过这个,但行为是一样的。我已经设置了TaskCreationOptions.LongRunning,所以无论如何TPL都应该启动一个新线程!!!