【问题标题】:How to call a method async with some kind of priority?如何以某种优先级调用异步方法?
【发布时间】:2009-02-14 00:22:43
【问题描述】:
我需要以不同的优先级异步调用几个方法。
我的第一个想法是使用 ThreadPool 并像这样更改 Thread 的优先级:
static void Run()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(SomeMethod));
}
static void SomeMethod(object o)
{
Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; // is this ok?
// do some work here
}
这行得通吗?或者你有什么建议?
【问题讨论】:
标签:
c#
.net
multithreading
asynchronous
threadpool
【解决方案1】:
根据http://msdn.microsoft.com/en-us/library/0ka9477y.aspx,如果你的目标是2.0,它不会起作用,它暗示3.5有一些差异,但没有特别提到优先级:
何时不使用线程池线程
有几种情况适合创建和管理自己的线程而不是使用线程池线程:
-
您需要一个前台线程。
-
您需要线程具有特定的优先级。
-
您的任务会导致线程长时间阻塞。线程池具有最大线程数,因此大量阻塞的线程池线程可能会阻止任务启动。
-
您需要将线程放入单线程单元中。所有 ThreadPool 线程都在多线程单元中。
-
您需要有一个与线程相关联的稳定身份,或者将线程专用于某项任务。
您可能需要提出自己的实现,并直接处理线程的创建。
问题:你想达到什么目标?你有一组任务要处理,你希望高优先级的任务先发生,低优先级的任务稍后发生;还是您真的想要不同优先级的线程?
【解决方案2】:
这绝对是一个可怕的想法。
一般来说,设置线程或进程优先级是一个坏主意,因为它是不确定的,并且您可能会饿死该行为中的其他线程/进程。此外,由于饥饿,您实际上可能会提升低优先级线程/进程的优先级。
最重要的是,线程池的线程是要被重用的,通过改变线程的优先级,你正在改变任务的期望,在你的例程运行后获得线程以供使用。
话虽如此,您有两个选择。如果您只需要确定任务的优先级并且不介意与您的任务无关的其他项目是否在您之前执行,那么您可以将线程池与生产者消费者模式一起使用,并使用一些包装器代码来获取最高优先级项目从您的队列中。
如果您希望线程只运行您的任务,那么您必须创建自己的线程池(使用 System.Thread 类)然后做同样的事情,使用包装代码让任务根据优先级执行.
.NET 4.0(尚未发布)中 System.Threading 命名空间中的新类将为您处理创建单独的线程池。
【解决方案3】:
我认为为了干净起见,您还应该在退出该方法时恢复线程优先级! (使用 try ... finally 或类似的东西)