任务管理的ID问题 [英] Task managed ID question

查看:85
本文介绍了任务管理的ID问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Task执行中,Thread.CurrentThread.ManagedThreadId是否保持不变,因为TaskThreadpool内执行并可以回收?

解决方案

<据我所知,System.Threading.Tasks.Task是通过在线程上自动映射来实现的,并且我们知道在Windows .NET线程是在OS线程(不是光纤或某些.NET特定机制)的基础上实现的.也就是说,系统不应保证每次任务执行其时间片时,当前执行的线程在所有情况下都是相同的.

您看,可以轻松地通过实验来确认它,但是问题是:如果观察到当前线程有时是不同的,它将确认它,但是如果观察到当前线程对于相同的任务是相同的,它不会证明任何事情.



微软文档间接证实了我所说的话: http://www.codeproject.com/script /Answers/Post.aspx?aid=407532 [在后台,将任务排队到ThreadPool,该线程池已通过确定(并爬山)算法确定并调整为使吞吐量最大化的线程.这使任务相对轻巧,您可以创建许多任务以启用细粒度的并行性.为了补充这一点,采用了广为人知的工作窃取算法来提供负载平衡.


从所有本文文档中,我看不到为什么必须保证任务实例由同一线程运行的原因.我认为最安全的说法是:这取决于实现.

[END EDIT]

如果您要尝试一下,请找到明确说明此问题的确切文档,请通过对此答案发表评论来通知我.

—SA


以下内容似乎可以正常使用:

 公共 静态  void  Main(字符串 [] args)
{
     for ( int  i =  0 ; i <   1000000 ; i ++)
        Task.Factory.StartNew(()= >  work());
}

私有 静态  void  work()
{
     int  i = Thread.CurrentThread.ManagedThreadId;
    dosomework(i, 0 );
}

私有 静态  void  dosomework( int  i, int  c)
{
    如果(c ==  3 )返回 ;
    Thread.Sleep( 1 );
     int  j = Thread.CurrentThread.ManagedThreadId;
    如果(i!= j)
        抛出 异常(" 失败");
    dosomework(i,++ c);
}


因此,就此测试而言,似乎调用链是在单个线程上执行的.


Within a Task execution does the Thread.CurrentThread.ManagedThreadId stay the same, given that the Task are executed within a Threadpool and are recycled?

解决方案

To best of my knowledge, System.Threading.Tasks.Task is implemented by automatic mapping on threads, and we know that on Windows .NET threads are implemented on the base of OS threads (not fibers or some .NET specific mechanism). That said, the system should not guarantee that every time a task is executing its time slice, the current thread being executed is the same in all cases.

You see, you can easily try to confirm it by experiment, but the problem is: if you observe that a current thread is sometimes different, it would confirm it, but if you observe that the current thread is the same for the same task, it would not prove anything.

[EDIT]

Indirectly, what I say is confirmed by Microsoft documentation:
http://www.codeproject.com/script/Answers/Post.aspx?aid=407532[^]:

Behind the scenes, tasks are queued to the ThreadPool, which has been enhanced with algorithms (like hill-climbing) that determine and adjust to the number of threads that maximizes throughput. This makes tasks relatively lightweight, and you can create many of them to enable fine-grained parallelism. To complement this, widely-known work-stealing algorithms are employed to provide load-balancing.


From all this documentation article, I don''t see a reason why a task instance should be guaranteed to run by the same thread. I think it would be safest to say: this is implementation-dependent.

[END EDIT]

If you go so far to try it out, of find out exact documentation explicitly explaining this matter, please notify me by commenting on this answer.

—SA


The following seems to work ok :

public static void Main(string[] args)
{
    for (int i = 0; i < 1000000; i++)
        Task.Factory.StartNew(() => work());
}

private static void work()
{
    int i = Thread.CurrentThread.ManagedThreadId;
    dosomework(i,0);
}

private static void dosomework(int i, int c)
{
    if (c == 3) return;
    Thread.Sleep(1);
    int j = Thread.CurrentThread.ManagedThreadId;
    if (i != j)
        throw new Exception("failed");
    dosomework(i,++c);
}


So as far as this test goes it seems that the call chain is executed on a single Thread.


这篇关于任务管理的ID问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆