ASP.NET의 비동기 기능 활용
비동기 프로그래밍은 최근 몇 년 동안 많은 주목을 받았는데, 그 이유는 주로 두 가지입니다. 첫째, UI 스레드를 차단하지 않고 처리가 끝나기 전에 UI가 나타나는 것을 방지하므로 더 나은 사용자 경험을 제공하는 데 도움이 됩니다. 인터페이스가 중단됩니다. 둘째, 추가 하드웨어를 추가하지 않고도 시스템을 크게 확장할 수 있습니다.
그러나 스레드 자체를 관리하기 위해 적절한 비동기 코드를 작성하는 것은 지루한 작업입니다. 그럼에도 불구하고, 그 엄청난 이점으로 인해 많은 신구 기술이 비동기 프로그래밍을 사용하기 시작했습니다. Microsoft는 .NET 4.0이 출시된 이후 이에 많은 투자를 했으며 이후 .NET 4.5에 async 및 Wait 키워드를 도입하여 비동기 프로그래밍을 그 어느 때보다 쉽게 만들었습니다.
그러나 ASP.NET의 비동기 기능은 처음부터 사용할 수 있었지만 마땅한 관심을 받지 못했습니다. 그리고 ASP.NET과 IIS가 요청을 처리하는 방식을 고려할 때 비동기 구현의 이점은 훨씬 더 클 수 있습니다. 비동기식을 통해 ASP.NET 응용 프로그램의 확장성을 쉽게 크게 향상시킬 수 있습니다. async 및 Wait 키워드와 같은 새로운 프로그래밍 구성이 도입됨에 따라 우리는 비동기 프로그래밍의 강력한 기능을 사용하는 방법도 배워야 합니다.
이 블로그 게시물에서는 IIS와 ASP.NET이 요청을 처리하는 방법에 대해 논의한 다음 ASP.NET에서 비동기식을 사용할 수 있는 위치를 살펴보고 마지막으로 비동기식 장면의 장점을 가장 잘 반영하는 몇 가지에 대해 논의합니다.
요청은 어떻게 처리됩니까?
모든 ASP.NET 요청은 최종적으로 ASP.NET 처리기에 의해 처리되기 전에 IIS를 통과합니다. 먼저 IIS가 요청을 받아 사전 처리를 한 후 ASP.NET으로 전송하고(ASP.NET 요청이어야 함) ASP.NET이 실제로 이를 처리하여 응답을 생성한 후 다시 응답을 보냅니다. IIS를 통해 클라이언트에. IIS에는 요청을 ASP.NET 대기열로 보내기 전에 요청을 대기열에서 빼고 IIS 모듈을 실행하는 작업을 담당하는 일부 작업자 프로세스가 있습니다. 그러나 ASP.NET 자체는 스레드를 생성하지 않으며 요청을 처리하기 위한 스레드 풀도 없습니다. 대신 CLR 스레드 풀을 사용하여 요청을 처리하기 위해 스레드를 얻습니다. 따라서 IIS 모듈은 ThreadPool.QueueUserWorkItem을 호출하여 CLR 작업자 스레드에서 처리할 요청을 대기열에 넣습니다. 우리 모두는 CLR 스레드 풀이 CLR에 의해 관리되고 자동으로 조정될 수 있다는 것을 알고 있습니다. 즉, 필요에 따라 프로세스를 생성하고 제거합니다. 또한 스레드를 만들고 삭제하는 것은 무거운 작업이므로 CLR 스레드 풀에서는 동일한 스레드를 여러 작업에 사용할 수 있습니다. 요청 처리 프로세스를 설명하는 다이어그램을 살펴보겠습니다.
위 이미지에서 볼 수 있듯이 요청은 먼저 HTTP.sys에서 수신되어 해당 커널 수준 응용 프로그램 풀 대기열에 추가됩니다. 그런 다음 IIS 작업자 스레드가 큐에서 요청을 가져와 처리한 후 ASP.NET 큐에 전달합니다. 요청이 ASP.NET 요청이 아닌 경우 IIS에서 자동으로 반환됩니다. 마지막으로 요청을 처리하기 위해 CLR 스레드 풀에서 스레드가 할당됩니다.
ASP.NET의 비동기 사용 시나리오는 무엇입니까?
모든 요청은 대략 두 가지 범주로 나눌 수 있습니다.
CPU Bound 클래스
I/O Bound 클래스
CPU Bound 클래스 요청에는 CPU 시간이 필요합니다. 그리고 동일한 프로세스에서 실행됩니다. I/O Bound 유형 요청 자체가 차단되며 I/O 작업을 수행하고 응답을 반환하기 위해 다른 모듈에 의존해야 합니다. 차단 요청은 애플리케이션 확장성을 향상시키는 데 주요 장애물이며, 대부분의 웹 애플리케이션에서는 I/O 작업을 기다리는 데 많은 시간이 낭비됩니다. 따라서 다음 시나리오는 비동기식 사용에 적합합니다.
다음을 포함한 I/O 바운드 클래스 요청:
데이터베이스 액세스
파일 읽기/쓰기
웹 서비스 호출
네트워크 리소스 액세스
SignalR과 같은 이벤트 기반 요청
여러 데이터 소스에서 데이터를 가져와야 하는 시나리오
예를 들어, 다음은 간단한 동기 페이지를 만든 다음 이를 비동기 페이지로 변환하는 것입니다. 이 예에서는 1000ms의 지연을 설정하고(대규모 데이터베이스 또는 웹 서비스 호출 등을 시뮬레이션하기 위해) 다음과 같이 WebClient를 사용하여 페이지를 다운로드합니다.
protected void Page_Load(object sender, EventArgs e) { System.Threading.Thread.Sleep(1000); WebClient client = new WebClient(); string downloadedContent = client.DownloadString("https://msdn.microsoft.com/en-us/library/hh873175%28v=vs.110%29.aspx"); dvcontainer.InnerHtml = downloadedContent; }
이제 페이지를 비동기 페이지로 변환합니다. 여기서는 주로 세 단계가 필요합니다.
페이지 지시문에 Async = true를 추가하여 아래와 같이 페이지를 비동기 페이지로 변환합니다.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Home.aspx.cs" Inherits="AsyncTest.Home" Async="true" AsyncTimeout="3000" %>
AsyncTimeout도 여기에 추가됩니다(선택 사항). 귀하의 필요에 따라 선택하십시오.
2.将此方法转换成异步方法。在这里把Thread.Sleep 与 client.DownloadString 转换成异步方法如下所示:
private async Task AsyncWork() { await Task.Delay(1000); WebClient client = new WebClient(); string downloadedContent = await client.DownloadStringTaskAsync("https://msdn.microsoft.com/en-us/library/hh873175%28v=vs.110%29.aspx "); dvcontainer.InnerHtml = downloadedContent; }
3.现在可以直接在 Page_Load (页面加载)上调用此方法,使其异步,如下所示:
protected async void Page_Load(object sender, EventArgs e) { await AsyncWork(); }
但是这里的 Page_Load 返回的类型是async void,这种情况无论如何都应该避免。我们知道,Page_Load 是整个页面生命周期的一部分,如果我们把它设置成异步,可能会出现一些异常情况和事件,比如生命周期已经执行完毕而页面加载仍在运行。 因此,强烈建议大家使用 RegisterAsyncTask 方法注册异步任务,这些异步任务会在生命周期的恰当时间执行,可以避免出现任何问题。
protected void Page_Load(object sender, EventArgs e) { RegisterAsyncTask(new PageAsyncTask(AsyncWork)); }
现在,页面已经转换成了异步页,它就不再是一个阻塞性请求。
笔者在 IIS8.5 上部署了同步页面和异步页面,并使用突发负载对两者进行了测试。测试结果发现,相同的机器配置,同步页面在2-3秒内只能提取1000个请求,而异步页面能够为2200多个请求提供服务。此后,开始收到超时(Timeout)或服务器不可用(Server Not Available)的错误。虽然两者的平均请求处理时间没有多大差别,但是通过异步页面,可以处理两倍以上的请求。这足以证明异步编程功能强大,所以应该充分利用它的优势。
ASP.NET中还有几个地方也可以引入异步:
编写异步模块
使用IHttpAsyncHandler 或 HttpTaskAsyncHandler 编写异步HTTP处理程序
使用web sockets 或 SignalR
结论
本篇博文中,我们讨论了异步编程,而且发现,新推出的async 和 await关键字,使异步编程变得十分简单。我们讨论的话题包括 IIS和ASP.NET如何处理请求,以及在哪些场景中异步的作用最明显。另外,我们还创建了一个简单示例,讨论了异步页面的优势。最后我们还补充了几个ASP.NET中可以使用异步的地方。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











C 언어에서 특수 문자는 다음과 같은 탈출 시퀀스를 통해 처리됩니다. \ n 라인 브레이크를 나타냅니다. \ t는 탭 문자를 의미합니다. char c = '\ n'과 같은 특수 문자를 나타 내기 위해 탈출 시퀀스 또는 문자 상수를 사용하십시오. 백 슬래시는 두 번 탈출해야합니다. 다른 플랫폼과 컴파일러마다 다른 탈출 시퀀스가있을 수 있습니다. 문서를 참조하십시오.

C에서 숯 유형은 문자열에 사용됩니다. 1. 단일 문자를 저장하십시오. 2. 배열을 사용하여 문자열을 나타내고 널 터미네이터로 끝납니다. 3. 문자열 작동 함수를 통해 작동합니다. 4. 키보드에서 문자열을 읽거나 출력하십시오.

C 언어 커버 산술, 할당, 조건, 논리, 비트 연산자 등의 기호의 사용 방법은 기본 수학 연산에 사용되며, 할당 연산자는 할당 및 추가, 곱하기, 분할 할당에 사용되며, 곱하기 및 분할 할당에 사용되며, 조건에 따라 조건 운영자가 사용되며, 비트 오퍼레이터에 사용되며, 스페셜 오퍼레이터는 비트 수준의 운영에 사용됩니다. 포인터, 파일 종료 마커 및 비수통 값.

C 언어에서 char와 wchar_t의 주요 차이점은 문자 인코딩입니다. char ascii를 사용하거나 ascii를 확장하고, wchar_t는 유니 코드를 사용합니다. Char는 1-2 바이트를 차지하고 WCHAR_T는 2-4 바이트를 차지합니다. Char는 영어 텍스트에 적합하며 WCHAR_T는 다국어 텍스트에 적합합니다. Char_t는 널리 지원되며, 컴파일러 및 운영 체제가 유니 코드를 지원하는지 여부에 따라 다릅니다. Char는 문자 범위가 제한되며 WCHAR_T는 더 큰 문자 범위를 가지며 특수 함수는 산술 작업에 사용됩니다.

멀티 스레딩과 비동기식의 차이점은 멀티 스레딩이 동시에 여러 스레드를 실행하는 반면, 현재 스레드를 차단하지 않고 비동기식으로 작업을 수행한다는 것입니다. 멀티 스레딩은 컴퓨팅 집약적 인 작업에 사용되며 비동기식은 사용자 상호 작용에 사용됩니다. 멀티 스레딩의 장점은 컴퓨팅 성능을 향상시키는 것이지만 비동기의 장점은 UI 스레드를 차단하지 않는 것입니다. 멀티 스레딩 또는 비동기식을 선택하는 것은 작업의 특성에 따라 다릅니다. 계산 집약적 작업은 멀티 스레딩을 사용하고 외부 리소스와 상호 작용하고 UI 응답 성을 비동기식으로 유지 해야하는 작업을 사용합니다.

C 언어에서 숯 유형 변환은 다른 유형으로 직접 변환 할 수 있습니다. 캐스팅 : 캐스팅 캐릭터 사용. 자동 유형 변환 : 한 유형의 데이터가 다른 유형의 값을 수용 할 수 있으면 컴파일러가 자동으로 변환됩니다.

char 어레이는 문자 시퀀스를 C 언어로 저장하고 char array_name [size]로 선언됩니다. 액세스 요소는 첨자 연산자를 통해 전달되며 요소는 문자열의 끝점을 나타내는 널 터미네이터 '\ 0'으로 끝납니다. C 언어는 strlen (), strcpy (), strcat () 및 strcmp ()와 같은 다양한 문자열 조작 함수를 제공합니다.

C 언어에는 내장 합계 기능이 없으므로 직접 작성해야합니다. 합계는 배열 및 축적 요소를 가로 질러 달성 할 수 있습니다. 루프 버전 : 루프 및 배열 길이를 사용하여 계산됩니다. 포인터 버전 : 포인터를 사용하여 배열 요소를 가리키며 효율적인 합계는 자체 증가 포인터를 통해 달성됩니다. 동적으로 배열 버전을 할당 : 배열을 동적으로 할당하고 메모리를 직접 관리하여 메모리 누출을 방지하기 위해 할당 된 메모리가 해제되도록합니다.
