이번 글은 C# BackgroundWorker의 사용법에 대한 자세한 설명을 위주로 소개하고 있는데, 편집자가 꽤 좋다고 생각해서 지금부터 공유하고 참고용으로 올려보겠습니다. 에디터를 따라가서 살펴보겠습니다.
C# 프로그램에는 시간이 오래 걸리는 CPU 집약적인 작업이 종종 있습니다. 이러한 작업을 UI 스레드에서 직접 수행하면 UI가 응답하지 않는 문제가 발생합니다. 발생하다. . 이런 종류의 문제를 해결하는 주요 방법은 멀티스레딩을 사용하고, 백그라운드 스레드를 시작하고, 이 백그라운드 스레드에서 컴퓨팅 작업을 완료하는 것입니다. 그러나 네이티브 인터페이스의 스레드 작업은 다소 어렵습니다. 스레드 간의 통신을 더 완성하려면 훨씬 더 어려울 것입니다.
다행히 .NET 클래스 라이브러리에서는 이런 문제를 좀 더 우아하게 해결할 수 있는 BackgroundWorker라는 클래스를 제공합니다. BackgroundWorker 클래스는 비교적 사용하기 간단하지만 아직 주의해야 할 세부 사항이 있습니다. 아래에서는 데모 프로그램을 통해 주요 사용법을 소개합니다. 데모에서는 1부터 100까지의 누적 합계를 계산합니다. 데모의 UI는
사용 개요입니다.
양식에 BackgroundWorker 인스턴스를 빌드하고 DoWork이벤트 처리 함수 에 시간이 많이 걸리는 작업을 추가한 다음 RunWorkerAsync 메서드를 호출합니다. 아아아아
좀 너무 단순한거 아닌가요? 그럼 다음 질문을 생각해 보겠습니다. 매개변수를 작업에 전달하려면 어떻게 해야 할까요?계산 과정에 매개변수 전달
계산 과정에 100을 직접 입력하는 것은 좋지 않습니다. 또한 사용자가 합계의 범위를 지정할 수 있도록 할 계획입니다. ! 따라서 계산 프로세스에 매개변수로 100을 전달해야 합니다. 개요에서는 RunWorkerAsync 메서드를 호출하여 계산 프로세스를 시작합니다. 실제로 이 메서드는 개체 유형 매개 변수를 허용할 수 있습니다. 이를 통해 모든 데이터를 계산 프로세스에 전달할 수 있습니다.private BackgroundWorker _demoBGWorker = new BackgroundWorker(); _demoBGWorker.DoWork += BGWorker_DoWork; _demoBGWorker.RunWorkerAsync(); private void BGWorker_DoWork(object sender, DoWorkEventArgs e) { //在这里执行耗时的运算。 int sum = 0; for (int i = 0; i <= 100; i++) { sum += i; } }
메시지를 UI로 전송
계산 과정이 상대적으로 길기 때문에진행률 표시줄을 통해 현재 진행 상황을 표시하는 반면, 또한 계산의 중간 결과를 실시간으로 UI에 표시할 수 있기를 바랍니다. 물론 BackgroundWorker는 이 사용 사례에 대한 훌륭한 지원도 제공합니다. 이를 통해 계산 프로세스 중에 UI 스레드에 메시지를 보낼 수 있습니다. 구체적인 메서드를 살펴보겠습니다.
//别忘了设置滚动条。 this.progressBarSum.Maximum = 100; _demoBGWorker.RunWorkerAsync(100); //下面是更新后的 BGWorker_DoWork 方法: private void BGWorker_DoWork(object sender, DoWorkEventArgs e) { //在这里执行耗时的运算。 int endNumber = 0; if(e.Argument != null) { endNumber = (int)e.Argument; } int sum = 0; for (int i = 0; i <= endNumber; i++) { sum += i; } }
_demoBGWorker.WorkerReportsProgress = true; _demoBGWorker.ProgressChanged += BGWorker_ProgressChanged;
private void BGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { //修改进度条的显示。 this.progressBarSum.Value = e.ProgressPercentage; //如果有更多的信息需要传递,可以使用 e.UserState 传递一个自定义的类型。 //这是一个 object 类型的对象,您可以通过它传递任何类型。 //我们仅把当前 sum 的值通过 e.UserState 传回,并通过显示在窗口上。 string message = e.UserState.ToString(); this.labelSum.Text = message; }
작업 취소
실행 중에 사용자가 현재 작업을 취소할 수 있도록 하는 것이 기본 설계이며 BackgroundWorker는 당연히 좋은 지원을 제공합니다.private void BGWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bgWorker = sender as BackgroundWorker; int endNumber = 0; if(e.Argument != null) { endNumber = (int)e.Argument; } int sum = 0; for (int i = 0; i <= endNumber; i++) { sum += i; string message = "Current sum is: " + sum.ToString(); //ReportProgress 方法把信息传递给 ProcessChanged 事件处理函数。 //第一个参数类型为 int,表示执行进度。 //如果有更多的信息需要传递,可以使用 ReportProgress 的第二个参数。 //这里我们给第二个参数传进去一条消息。 bgWorker.ReportProgress(i, message); Thread.Sleep(600); } }
루프 :
_demoBGWorker.WorkerSupportsCancellation = true;
버튼이 감지되면 현재 계산 프로세스를 종료하세요. 다음은 취소 버튼을 클릭할 때 호출되는 코드입니다.
bgWorker.ReportProgress(i, message); Thread.Sleep(600); //在操作的过程中需要检查用户是否取消了当前的操作。 if (bgWorker.CancellationPending == true) { e.Cancel = true; break; }
_demoBGWorker.CancelAsync();
_demoBGWorker.RunWorkerCompleted += BGWorker_RunWorkerCompleted; private void BGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //如果用户取消了当前操作就关闭窗口。 if (e.Cancelled) { this.Close(); } //计算已经结束,需要禁用取消按钮。 this.btnCancel.Enabled = false; //计算过程中的异常会被抓住,在这里可以进行处理。 if (e.Error != null) { Type errorType = e.Error.GetType(); switch (errorType.Name) { case "ArgumentNullException": case "MyException": //do something. break; default: //do something. break; } } //计算结果信息:e.Result //use it do something. }
위 내용은 C#에서 BackgroundWorker 사용법에 대한 자세한 설명(그림)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!