.NET 4.0“작업 병렬 라이브러리”의 진행 상황보고 및 증분 결과 지원

StackOverflow https://stackoverflow.com/questions/1535749

문제

나는 그것을 알고있다 작업 병렬 라이브러리 여전히 베타 버전에 있으며 자원이 적을 가능성이 적지 만 내가 읽은 내용에서 도서관은 매우 특별한 대우를 제공합니다. 작업 일정, 예외 처리 그리고 해제.

그러나 나는 어떤 언급도 찾지 못한다 진행 상황보고 그리고 증분 결과를 보냅니다 작업에서. 이 두 가지는 무시하기에는 너무 중요해 보입니다. 작업 병렬 라이브러리에서이를 처리하는 방법에 대해 약간의 빛을 발하거나 설명하는 기사를 참조 할 수 있습니까?

도움이 되었습니까?

해결책

이 예제는 진행률 표시 줄을 업데이트합니다.

using System;   
using System.Threading;   
using System.Threading.Tasks;   
using System.Windows.Forms;   

class SimpleProgressBar : Form   
{   
    [STAThread]   
    static void Main(string[] args)   
    {   
        Application.EnableVisualStyles();   
        Application.Run(new SimpleProgressBar());   
    }   

    protected override void OnLoad(EventArgs e)   
    {   
        base.OnLoad(e);   

        int iterations = 100;   

        ProgressBar pb = new ProgressBar();   
        pb.Maximum = iterations;   
        pb.Dock = DockStyle.Fill;   
        Controls.Add(pb);   

        Task.ContinueWith(delegate   
        {   
            Parallel.For(0, iterations, i =>  
            {   
                Thread.SpinWait(50000000); // do work here   
                BeginInvoke((Action)delegate { pb.Value++; });   
            });   
        });   
    }   
}  

평행 한 내부에서 진행률 표시 줄을 업데이트합니다

다른 팁

이것은 내 최고 검색 결과 중 하나이며 여전히 진행에 대한 예제가 없습니다. Task Parallel Library 바로 여기에...

오늘 나는 새로운 멀티 스레드 애플리케이션을 개발하고 싶지만 사용하지 않고 TPL을 발견했습니다. BackgroundWorker (전에는 좋은 코드로 작업에 대해 어딘가에 읽었으므로)

나는 @stephen Cleary Answer에서 예제를 컴파일합니다. 그의 링크는 진행 상황과 다른 웹 사이트를 찾기 위해 매우 복잡합니다.

이것은 어떻게하는지에 대한 매우 간단한 예입니다. 진전 그리고 완전한 UI 스레드 안전 방법 :

        TaskScheduler currentTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        Task<string>.Factory.StartNew(() =>
        {
            // loop for about 10s with 10ms step
            for (int i = 0; i < 1000; i++)
            {
                Thread.Sleep(10);
                Task.Factory.StartNew(() =>
                {
                    // this is a task created each time you want to update to the UI thread.
                    this.Text = i.ToString();
                }, CancellationToken.None, TaskCreationOptions.None, currentTaskScheduler);
            }
            return "Finished!";
        })
        .ContinueWith(t =>
        {
            // this is a new task will be run after the main task complete!
            this.Text += " " + t.Result;
        }, currentTaskScheduler);

코드는 10 초 이내에 1 ~ 1000을 표시 한 다음 "마무리!" Windows 양식 제목 표시 줄에 문자열이 있습니다. TaskScheduler가 기본 스레드에서 실행될 예정인 작업이 실행될 것으로 생각되기 때문에 TaskScheduler가 UI 스레드 안전 업데이트를 만드는 까다로운 방법임을 알 수 있습니다.

배경 노동자가 가진 것과 같은 이에 대한 내장 지원은 없습니다.

SynchronizationContext를 직접 사용할 수 있습니다. 여기에는 훌륭한 비디오가 있습니다. http://www.rocksolidknowledge.com/screencasts.mvc/watch?video=tasksandthreadaffinity.wmv

저자는이 비디오에서 두 가지 솔루션을 개발합니다. 하나는 SynchronizationContext를 사용하고 다른 하나는 작업 연속을 사용합니다. 문제의 경우 연속이 작동하지 않지만 SynchronizationContext 접근 방식은 잘 작동합니다.

추신 재사용 가능한 코드를 작성하는 경우 SynchronizationContext.Current를 캡처하면 NULL을 테스트하고 (NULL 인 경우) 대신 기본 구성 동기화 콘텐츠를 사용해야합니다.

업데이트: 이것에 대한 코드를 게시했습니다 내 블로그에서. 내 솔루션은 실제로 a를 기반으로합니다 Task 그것은 UI 스레드로 다시 예정되어 있습니다. TaskScheduler 사용하는 SynchronizationContext 아래에. 허용 된 답변과 달리이 솔루션은 WPF 및 Windows 양식 모두에서 작동합니다.

TPL은 특히 UI 지원을 지향하지 않으며,이를 위해 배경 워크를 사용할 수 있습니다. 중간 결과를 보내거나 처리 할 때,이를 지원하기위한 새로운 CollectionClasses (동의어)가 있습니다.

비동기 작업에서 진행 상황을보고하려면 iprogress 비동기 방법으로. 방법 내에서 호출하십시오 보고서 진행 데이터와 함께. 발신자는 해당 진행 보고서를 처리하는 방법을 결정할 수 있습니다 (즉, 무시하거나 UI를 업데이트).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top