常量循环 - 线程与异步,最佳实践

时间:2014-03-26 13:54:05

标签: c# task-parallel-library async-await

我有一些常见的代码,在我们的一些内部应用程序中,我似乎经常使用它。

public State SomeState { get; set; }
Thread thread = new Thread(ThreadProc)
thread.Start();

void ThreadProc() {
    while(isTrue){
       //Changes SomeState after ping
       //Can take up to 5 seconds to complete if service is unavailable
       PingServiceTocheckState(); 
       UpdateUI();
       Thread.Sleep(200);
    }
}

void UpdateUI() {

    if (InvokeRequired)
    {
        Invoke(new MethodInvoker(UpdateUI));
        return;
    }

    if(SomeState == State.Up){
        //set these UI values (txt.Text = ...)
    }
    ......
}

常量操作可能是在Windows窗体上更新Ui或不断从网络流中读取。

与TPL和Async相比,我觉得这可能已经过时了。

我是否认为可以使用Async / TPL更好地管理? 如果是这样,有人能举例说明我将如何使用这些新想法完成上述工作吗?

*注意:我目前偶尔使用异步,我试图让它在我的编码中更流行,但我在使用异步创建一个长期运行的“后台线程”的最佳方法上有点迷失。

修改

我已经更新了我的示例,其中包含了与我当前项目相关的更多细节。我在UserControl中有类似的代码。然后我有一个Windows窗体,动态添加约50个这些控件。如果没有Thread,表单基本上会挂起,线程一切都运行顺畅。我只想到,而不是自己管理线程async / TPL比我自己更有效地管理任务(Ping和Update)。

2 个答案:

答案 0 :(得分:5)

TPL非常适合持续时间较短的任务 - 因为您基本上是在使用池中的工作人员。如果您的操作是连续的,则专用线程是完全合适的。但是,如果PerformAction实际上阻止等待进入队列的数据,并且实际上只是非常短暂地偶尔执行任何操作,那么是:TPL可能会重新发挥作用。但是有一个顺序与并发编程的问题:目前,在那种情况下,你将按顺序处理事物。 TPL没有这样的保证,并且旨在同时处理事情。当然可以编写使用 TPL(或者只是regualar ThreadPool)来处理顺序队列的代码,但它有点复杂,并且有边缘情况围绕“是否有当前的工人?我需要开始一个吗?是吗?”的问题。

答案 1 :(得分:0)

ThreadTPLAsync站在相同操作系统内核对象和工件的肩膀上。它们只是为您提供不同功能的不同类。

它们都没有为您提供对线程的真正低级控制,但是,例如TPL如果可以,则将您的任务拆分到CPU的不同内核中,并发现一般情况在多核现代处理器上并行处理任务的最佳方式,因此往往更快,更轻巧。

因此TPL是您应用中多线程处理的建议库,如果您拥有并且可以使用最新的.NET框架。