FromCurrentSynchronizationContext,나는 뭔가?
-
12-12-2019 - |
문제
나는 현재 작업을 읽는 응용 프로그램에서 큰 바이너리 파일에 보유하는 여러 가지 수천 파일에 있는 모든 파일 처리되는 다른 클래스 이용해 주시기 바랍니다.이 클래스의 반환하거나 객체이거나 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);