문제

나는 현재 작업을 읽는 응용 프로그램에서 큰 바이너리 파일에 보유하는 여러 가지 수천 파일에 있는 모든 파일 처리되는 다른 클래스 이용해 주시기 바랍니다.이 클래스의 반환하거나 객체이거나 null.을 진행 중에 주요 형태가 있지만 몇 가지 이유가 얻을 수 없습니다 우리는 어리습니다.

int TotalFound = 0;
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext;
BufferBlock<file> buffer = new BufferBlock<file>();
DataflowBlockOptions options = new DataflowBlockOptions(){ TaskScheduler = uiScheduler, }; 
var producer = new ActionBlock<someObject>(largeFile=>{ 
    var file = GetFileFromLargeFile(largeFile);
    if(file !=null){
       TotalFound++;
       buffer.post(file);
       lblProgress.Text = String.Format("{0}", TotalFound);
    }
}, options);

위의 코드는 안전한 액세스를 제공 형태로,심지어 내가 사용하는"알아보도록 하자.FromCurrentSynchronizationContext",왜?기 때문에 코드를 사용하여 아래 양식을 업데이트 미

DataflowBlockOptions options = new DataflowBlockOptions(){ TaskScheduler = uiScheduler, }; 
var producer = new ActionBlock<someObject>(largeFile=>{ 
    var file = GetFileFromLargeFile(largeFile);
    if(file !=null){
       Task.Factory.StartNew(() => {
          TotalFound++;
          buffer.Post(file);
       }).ContinueWith(uiTask => {
          lblProgress.Text = String.Format("{0}", TotalFound);
       },CancellationToken.None, TaskContinuationOptions.None, uiScheduler);           
    }
});

나는 새로운 이 전체 TPL 데이터 흐름,그래서 내가 누군가를 희망을 공유할 수 있는 몇 가지 빛 이유에서 두 번째 코드 그것은 작품에서 첫 번째 코드 그렇지 않습니다.

종류 감사합니다, Uml 정적 구

도움이 되었습니까?

해결책

하는 이유는 UI 는 차단되는 기술을 테스트 당신이 사용하는 FromCurrentSynchronizationContext.그것이 원인 코드를 실행하는 UI 스레드에서 의미하는 것이 얼 하는 경우 몇 가지 오래 실행되는 작업(가장 가능성 GetFileFromLargeFile()).

다른 한편으로는,당신은 실행 lblProgress.Text 니다.

나는 확실하지 않다 설정해야 합니다 lblProgress.Text 에서 직접 이 코드,그것처럼 너무 꽉게 결합하는 나입니다.하지만 당신이 원하는 경우에는,나는 당신을 실행해야 하는 라인에 UI 실:

var producer = new ActionBlock<someObject>(async largeFile =>
{
    var file = GetFileFromLargeFile(largeFile);
    if (file != null)
    {
        TotalFound++;
        await buffer.SendAsync(file);
        await Task.Factory.StartNew(
            () => lblProgress.Text = String.Format("{0}", TotalFound),
            CancellationToken.None, TaskCreationOptions.None, uiScheduler);
    }
});

하지만 더 나은 솔루션을 것이 당신 GetFileFromLargeFile() 비동기와 만들어지지 않는 모든 오래 실행되는 작업에 UI 스레드(ConfigureAwait(false) 당신을 도울 수 있습니).았을 경우에는 코드 ActionBlock 을 실행할 수 있는 UI 스레드에서 냉동하지 않고의 UI 를:

var producer = new ActionBlock<someObject>(async largeFile =>
{
    var file = await GetFileFromLargeFile(largeFile);
    if (file != null)
    {
        TotalFound++;
        await buffer.SendAsync(file);
        lblProgress.Text = String.Format("{0}", TotalFound)
    }
}, options);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top