Windows Phone 中的后台线程

11

在我进行Windows Phone 7应用程序开发的经验中,我注意到有多种方法可以在异步线程中运行操作。

  1. System.Threading.Thread
  2. System.ComponentModel.BackgroundWorker
  3. System.Threading.ThreadPool.QueueUserWorkItem()

除了前两种方法更易追踪之外,我没有看到这些方法之间有任何明显的区别。

在使用这些方法之前,您是否考虑过什么?您会选择哪个方法,并为什么选择它?


除了明显的线程与线程池讨论,你还有其他意见吗? - Tudor
这可能取决于你想做什么,你列出了3种非常不同的线程模型(基本、UI和托管池),你是否阅读了MSDN等资料... http://www.albahari.com/threading/ http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx - Lloyd
@Lloyd 实际上,Bgw 运行在线程池之上,在 SL 中,线程通常与 UI 相关,因此 2 == 3。 - H H
每个人在Windows Phone开发中的偏好是这个问题的主题。 - Mo Valipour
@Henk 嗯,没错,但即使在 Silverlight 中它们仍然是3个单独的线程模型。 - Lloyd
4个回答

15

这个问题已经有了答案,但是我认为答案缺少了一些细节。

让我们依次来看。

System.Threading.Thread

所有线程(至少在CLR中)最终都由该类表示。但是你可能包含它是为了查询何时需要自己创建实例。

答案很少。通常,在日常工作中调度后台任务的重要工具是Threadpool。但是,在某些情况下,我们确实需要创建自己的线程。通常这样的线程会在大部分应用程序运行时存在。它将在某些等待句柄上被阻塞并花费大部分时间。偶尔,我们会发出此句柄的信号并唤醒它以执行一些重要操作,然后它就会回到睡眠状态。对于此操作,我们不使用Threadpool工作项,因为我们不能容忍它可能排队在一组未完成的任务后面,其中一些任务本身(可能无意中)被阻塞在其他等待句柄上。

System.ComponentModel.BackgroundWorker

这是一个友好的类封装,可以使用线程池工作项。这个类仅面向UI导向的开发人员,他们偶尔需要使用后台线程。它的事件在UI线程上分派,使其易于消耗。

System.Threading.ThreadPool.QueueUserWorkItem

这是当您需要在后台线程上执行某些任务时的日常工作工具。这消除了为执行某些任务分配和释放单个线程的开销。它限制了线程实例的数量,以防止太多的操作尝试并行运行而占用太多可用资源。

QueueUserWorkItem是我首选的调用后台操作的选项。


很好的回答。只想补充一下,ThreadPool.QueueUserWorkItem和BackgroundWorker都可以使用后台线程。这意味着当应用程序关闭时,线程将立即终止。如果您需要在不同的线程上执行工作,并且它必须在用户退出应用程序时完成,则需要直接使用Thread类并将IsBackground设置为false。 - calum
1
@calum:很好的观点,但我不确定在 WP7/Silverlight 中退出应用程序会发生什么。尽管 Thread 类的 IsBackground 属性得到支持,但根据文档,“两者之间的行为没有区别”。 - AnthonyWJones
嗯...这可能解释了我注意到的一些随机数据损坏。我想我需要运行一些测试来看看真正发生了什么。谢谢提醒。 - calum

1

每个人在Windows Phone开发中的偏好是这个问题的主题。 - Mo Valipour
我仍然会质疑你在做什么,是进行某种形式的客户端服务器交互,可能不会更新UI,还是在后台加载数据以更新UI,或者触发一个方法调用,该调用可以在有空闲线程时运行(可以辩称为非事务性),并且可能会更新UI。 - Lloyd
更新用户界面是一个重要的问题吗?我们不能在任何后台线程中使用 Deployment.Dispatcher 来更新用户界面吗? - Mo Valipour
1
Silverlight的用户界面在很大程度上依赖资源,因此任何占用界面资源的操作都会影响其性能。如果您有一个基本的LOB应用程序,那么将调用传送回到UI可能不是一个问题,但如果您有一个动态UI,受用户输入和动画的影响,则需要考虑如何管理线程资源以及何时进行管理。 - Lloyd
顺便提一下,当我说“资源依赖”时,我的意思是它受到Silverlight框架和CLR的限制,与Windows .Net Framework相比。 - Lloyd

1

你没有说明“为什么”,但是

  1. 基本线程 - 相当昂贵,不适用于小型任务
  2. Backgroundworker - 主要用于UI + 进度条工作
  3. ThreadPool - 用于小型独立任务

我认为TPL在SL中不受支持,这很遗憾。


如果您所说的TPL是指线程池,我认为它可以在Windows Phone上工作。 - Mo Valipour
不,TPL = 任务并行库。 - H H
哦,是的,我应该把那个可怜的东西翻倍 :) - Mo Valipour

0

当您的线程进展时,如果您的UI需要更新,则后台工作程序往往更好使用,因为它会在UI线程上处理调用回调函数(例如OnProgress回调),而不是在后台线程上。其他两个不会执行此操作。这取决于您自己来完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接