2017-11-13 1 views
-4

샘플 코드는 아래 : 그들은 같은 변수를 사용하고 있기 때문에동일한 변수 이름을 다른 BackgroundWorker 스레드에 재사용 할 수 있습니까?

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    string var1 = "sample 1"; 
    //display in UI var1 
    string var1 = "sample 1.1"; 
    //display in UI var1 
} 

private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) 
{ 
    string var1 = "sample 2"; 
    //display in UI var1 
    string var1 = "sample 2.1"; 
    //display in UI var1 
} 

private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e) 
{ 
    string var1 = "sample 3"; 
    //display in UI var1 
    string var1 = "sample 3.1"; 
    //display in UI var1 
} 

그것은 스레드가 둔화의 원인이됩니까? 그렇지 않으면 값이 항상 변경되기 때문에 UI에 잘못된 값이 표시됩니까? 내 프로그램에는 많은 스레드가 있으므로 잠재적 인 예상치 못한 결과가 걱정됩니다.

+0

어떤 의미에서 동일한 변수를 사용하고 있습니까? 그리고 어떤 가치가 변화하고 있습니까? –

+2

당신이 묻는 것이 명확하지 않습니다. 표시하는 각 스레드에는 현재 다른 곳에서는 사용되지 않는 로컬 문자열 변수가 있습니다. – mnistic

+0

죄송합니다. 코딩을 편집했습니다. – user107257

답변

1

이들은 local variables입니다. 이들은 서로 독립적으로 존재하며 컴파일러와 런타임은 ... 로컬 선언 된 위치에 있기 때문에 결코 혼합되지 않습니다. 실제로 로컬 변수는 스레딩에 대한 고려 사항이 아니며 Thread safety and local variables [*]을 참조하십시오.

일단 컴파일되면 로컬 변수의 이름이 손실됩니다 (이는 - local variable 1, local variable 2 등 ...과 동일합니다). 즉, Microsoft 중급 언어에서는 로컬 변수의 이름이 적합하지 않습니다. OpCodes.Ldloc Field을 참조하십시오.

스레드가 동일한 변수를 사용하고 있기 때문에 속도가 느려 집니까?

아니요. 이는 근심이 아닙니다. 이 지역 변수들은 서로 관련이 없습니다.

값이 항상 변경되기 때문에 잘못된 값이 UI에 표시됩니까?

이것은 변수 이름에 관계없이 발생할 수 있습니다. 중요한 것은 UI에 표시되는 가치와 언제, 어디에서 표시 할 수 있는지입니다. 변수를 보유하고있는 변수의 이름은 아무런 영향을 미치지 않습니다.

내 프로그램에는 많은 스레드가 있으므로 잠재적 인 예기치 않은 결과가 걱정됩니다.

걱정하지 마세요. 스레드간에 공유 메모리의 일부 형식에 대해 이야기하기 시작하면 걱정할 필요가 있습니다. 그리고 아니요, 로컬 변수는 스레드간에 공유되지 않으므로 여기에서 명확히하겠습니다 : 이들은 로컬 [**]입니다.

Joseph Albahari의 시리즈 Threading in C#을 제안하고 싶습니다. 구식인데도 불구하고 어느 쪽이 잘 쓰여졌는지, 명확한 예가 있으며, 모든 기본을 이해할 수 있습니다.


위와 같이 명명 변수는 코드의 가독성과 유지 관리 측면에서 중요합니다. 어쨌든, 나는 설교 분위기가 아닙니다. 그래서, 당신은 당신을 해. 나는이 문제에 대해서만 말할 것입니다 : 다음에 변수를 보았을 때 그 변수가 무엇인지 또는 다른 변수를 사용할 지 모를 때 생각해보십시오.


[*] 다음 answer to the linked question 로컬 변수가 노출 될 수있는 두 가지 방법을 언급한다. 두 변수 모두 로컬 변수를 비공개 객체의 필드로 업그레이드합니다 (yield return은 에 값을 복사하고 반면에 로컬 변수에 closure을 만들고 공유하면 로컬 변수를 공유 함) 숨겨진 익명 클래스에서).

[**] : async/await을 사용 중이지만 다른 스레드에서 메소드가 다시 시작된 경우 두 개의 스레드가 로컬 변수를 공유 할 가능성이 없습니다 (손이 바뀌지 만 걱정하지 않아도됩니다. 당신이 ThreadLocal 또는 이와 유사한 것을 사용하지 않는 한).

[***] : 요즘 우리는 async/await을 사용하고 있습니다. 실제로 BackgroundWorker을 사용하고 계십니까?

+0

글쎄, 내가 여기에서 시도하고 backgroundWorker multithreading 처리의 더 쉽고 편리한 방법에 대한 조언을 얻었습니다. 거기에 backgroundWorker 어떤 문제가 있습니까? 덕분에 – user107257

+0

. 나는 당신의 대답이 내 의구심을 극복했다고 생각합니다. – user107257

+0

@ user107257'BackgroundWorker'가 작동합니다. 틈새 유스 케이스는 의도 된 용도 인 UI에 있습니다. [장기 실행 작업 중 WinForm 응용 프로그램 UI 응답이 멈 춥니 다] (https://stackoverflow.com/a/1216799/402022), 이전 버전에서는 'async/await'가 존재하지 않았습니다. 'async/await'는 앞으로의 추천입니다. 그렇다고해서 BackgroundWorker를 없앨 수는 없습니다 (믹스 할 수도 있습니다). 참고 항목 : [Async in 4.5 : Async API에서 진행 및 취소 사용] (https://blogs.msdn.microsoft.com/dotnet/2012/06/06/async-in-4-5-enabling-progress-and- cancellation-in-async-apis /). – Theraot

관련 문제