2012-04-25 3 views
1

나는 쉽게 할 수있을 것이라고 생각하지만 내 함수 내에서 레이블에 쓰는 방법을 알아낼 수는 없습니다.정적 함수에서 레이블에 작성하기

public static void StartProcessing(object data) 
{ 

    lblError.Text = "Blah Blah" 
} 

나는

그래서 내가 레이블의 새로운 인스턴스를 생성하고 그것을 추가하는 시도 "... 객체 참조가 비 정적 필드, 메서드 또는 속성이 필요합니다"오류를 얻을 제어 (패널)하지만 lblError의 새 인스턴스가이 작업을 수행하는 쉬운 방법이있을
public static void StartProcessing(object data) 
    { 
     Panel Panel1 = new Panel(); 
     Label lblError= new Label(); 
     Panel1.Controls.Add(lblError); 

     lblError.Visible = true; 
     lblError.Text = "Blah Blah"; 

    } 

을 표시하기되지 않는 이유는 무엇입니까? 어느 간과 했어 ..

함수는 다음과 같이 호출됩니다. 위의 두 번째 줄에 정적 메시지가 아닌 것을 변경하면 "다음과 같은 동일한 오류 메시지가 나타납니다. - 정적 필드, 메서드 또는 속성 ... "이 함수가 정적이 아닌 경우?

public object LaunchNewProcess(object data) 
{ 
ThreadPool.QueueUserWorkItem(
       new WaitCallback(ProcessStatuses.StartProcessing), 
       new object[] {newProcess, allProcesses} 
       ); 
+7

왜 메서드가 정적입니까? 그게 문제예요 ... –

+0

이제는 당신이 당신의 기능을 어떻게 부르는 지 보았습니다. – SouthShoreAK

+0

프로세스 중 하나가 실패한 경우 오류 메시지가 사용자에게 표시되기를 원합니다. – user1186144

답변

5

당신이 그것을 호출 할 때 정적 함수에 라벨을 전달합니다 컨트롤이 페이지의 예를 (클래스)에 속해 있기 때문에

public static void StartProcessing(object data, Label lblError) 
{ 

    lblError.Text = "Blah Blah" 
} 

정적 기능을 컨트롤에 액세스 할 수 없습니다 .

정적은 클래스의 모든 인스턴스가 동일한 함수 또는 변수를 공유한다는 것을 의미합니다. 따라서 클래스의 인스턴스는 정적 변수 또는 함수에 액세스 할 수 있습니다. 그러나 정적은 클래스의 모든 인스턴스를 "인식"하지 않으므로 인스턴스의 멤버를 액세스 할 수 없습니다. 사실, 정적 메소드 또는 변수는 클래스의 인스턴스가 존재할 필요가 없기 때문에 어떻게 할 수 있습니까?

함수에서 static 키워드를 제거하면 다른 사람들이 언급했듯이 작동하지만, 사용자가 이유 때문에 정적이라고 가정하고 있습니다.

편집 좋아, 이것은 더 복잡합니다.

그래서 일련의 스레드를 실행하는 클래스가 있으며 문제가 발생하면 사용자에게 표시되기를 원하십니까? 글쎄, 페이지의 인스턴스없이 페이지의 컨트롤에 액세스 할 수 없기 때문에 현재의 접근 방식에 결함이 있습니다. 또한이 접근 방식이 페이지 수명주기 내에서 어떻게 적용되는지 확신 할 수 없습니다.

//do this before you start spawning threads 
List<bool> successes = new List<bool>(); 

ThreadPool.QueueUserWorkItem(
      new WaitCallback(ProcessStatuses.StartProcessing), 
      new object[] {newProcess, allProcesses, successes} 
      ); 

//you MUST wait for all your threads to complete before proceeding! 
if(successes.Any(s => !s)) 
{ 
    //update your error label 
} 

public static void StartProcessing(object data, Label lblError) 
{ 
    var dataArray = (object[3]) data; 
    //if there is an error 
    dataArray[2] = false; 
} 
+0

라벨이있는 폼의 일부가 아닌 클래스 파일 (.cs)에서 함수가 호출됩니다! 이런 식으로 레이블을 전달할 수 있을지 확실하지 않으십니까? – user1186144

+1

우. 그것은 여러 수준에서 문제입니다. 다른 클래스가 페이지 인스턴스없이이 함수를 호출하면 레이블은 항상 null이됩니다. 소스를 올리면 잘못된 방향으로 움직일 수 있습니다. – SouthShoreAK

+0

비서 작업이 마누엘에서 끝날 때까지 기다리면 모든 것이 끝날 때까지 사용자는 빈 화면에 앉아 있습니다. 이것은 작업을 비동기로 만드는 목적을 무효화하고 기존 스레드에서 모든 작업을 순차적으로 수행 할 수 있습니다. 대안에 대한 내 대답을 참조하십시오. – Servy

2

싶은 것은 실제로는 매우 어렵습니다 :

가장 좋은 방법이 같은 수 (코드의 부족 죄송합니다, 구현에 많이 의존하는 것).

페이지를 만들고 비동기 작업을 시작한 다음 사용자에게 페이지를 보내고 비동기 작업이 끝난 후 페이지의 콘텐츠를 업데이트하려고합니다.

문제는 비동기 작업이 완료 될 때까지 이미 페이지가 전송되었으며 응답을 보낸 후에 HTTP가 작동하는 방식에 기반합니다. 클라이언트와 더 많이 대화하지 않습니다. 클라이언트를 업데이트하려면 클라이언트가 다른 요청을 보낼 때까지 기다려야합니다.

즉, 기본적으로 서버에 폴링하는 JavaScript 코드가 있어야한다는 의미입니다. "아직 끝났습니까? 아직 끝났습니까? 아직 끝났습니까?" 결국 서버는 "예, 페이지에 표시 할 항목이 있습니다"라고 말합니다.

다행히도 처음부터 다시 시작할 필요는 없습니다. Here이 모든 것을 수행하는 Microsoft의 예제를 찾을 수 있습니다. 필요에 맞게 수정할 수 있습니다. 또한 프로그램을 작성하는 것 외에도 서버를 지속적으로 폴링하기 위해 많은 리소스를 소비하므로 실제로이 작업을 수행해야합니다.

옵션 2는 새 스레드에서 다른 작업을 시작하지 않고 페이지가 사용자에게 반환되기 전에 코드를 순차적으로 실행하는 것입니다. 빈 화면을 한동안 쳐다 보지만 프로그램하기가 훨씬 쉬울 것입니다. 태스크가 정말로 오래 실행되는 경우, 여기를 계속 주시하기 위해 하나의 크기가 제한 시간에 있습니다.

+0

그는 자신의 모든 스레드가 완료되기를 기다릴 수 있습니다. 섬기는 사람. 그래도 좋은 설명. – SouthShoreAK

+0

@SouthShoreAK 귀하의 답변에 댓글을 달았습니다. 그렇다면 왜 다른 스레드를 시작해야합니까? 나는이 대답으로 그 옵션을 편집했다. – Servy

+0

@SouthShoreAK 아, 그리고 내 대답에 갇혀있어, 당신이 작업을 기다리는 경우 시간 초과 클라이언트와 잠재적 인 문제가 있습니다. – Servy

관련 문제