- Controller.csv: 컨트롤러 설정 정보 - HC900-PID.txt: PID 파라미터 참조 - HW_Universal_Modbus/: HC900 Modbus 통신 매뉴얼 - 작업지시서-대소문자-DB정합성: 대소문자 DB 정합성 작업 지시 - WARNING-문제점: 프로젝트 이슈 트래킹
164 lines
5.3 KiB
Markdown
164 lines
5.3 KiB
Markdown
# 경고: async 메서드에서 await 미사용 (CS1998)
|
|
|
|
## 경고 요약
|
|
|
|
```
|
|
warning CS1998: This async method lacks 'await' operators and will run synchronously.
|
|
Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)'
|
|
to do CPU-bound work on a background thread.
|
|
```
|
|
|
|
## 문제 설명
|
|
|
|
C#에서 `async` 키워드를 붙인 메서드 내부에 `await`가 하나도 없습니다.
|
|
이 경우 컴파일러는 경고를 출력하고, 메서드는 **동기적으로 실행**됩니다.
|
|
`async/await`의 비동기 이점을 전혀 살리지 못하는 상태입니다.
|
|
|
|
## 발생 위치 및 상세
|
|
|
|
### 1. Hc900DbContext.cs:1306 - `ClearRecordsAsync()`
|
|
|
|
```csharp
|
|
public async Task<int> ClearRecordsAsync()
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: `async Task<int>` 반환형인데 `await` 없음. `throw`는 동기 연산.
|
|
- **원인**: OPC UA 관련 메서드로서 HC900Crawler에서는 사용하지 않는 스텁 메서드.
|
|
|
|
### 2. Hc900DbContext.cs:1311 - `BuildMasterFromRawAsync()`
|
|
|
|
```csharp
|
|
public async Task<int> BuildMasterFromRawAsync(bool truncate = false)
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: 동일하게 `async` 키워드만 있고 `await` 없음.
|
|
- **원인**: OPC UA 기반 빌드 메서드, HC900Crawler에서는 미사용.
|
|
|
|
### 3. Hc900DbContext.cs:1319 - `GetNameListAsync()`
|
|
|
|
```csharp
|
|
public async Task<IEnumerable<string>> GetNameListAsync()
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: `async` 키워드만 있고 `await` 없음.
|
|
- **원인**: OPC UA 관련 메서드, HC900Crawler에서는 미사용.
|
|
|
|
### 4. Hc900DbContext.cs:1324 - `GetMasterStatsAsync()`
|
|
|
|
```csharp
|
|
public async Task<NodeMapStats> GetMasterStatsAsync()
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: `async` 키워드만 있고 `await` 없음.
|
|
- **원인**: OPC UA 관련 메서드, HC900Crawler에서는 미사용.
|
|
|
|
### 5. Hc900DbContext.cs:1337 - `BuildRealtimeTableAsync()`
|
|
|
|
```csharp
|
|
public async Task<int> BuildRealtimeTableAsync(IEnumerable<PointBuilderGroupDto> groups)
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: `async` 키워드만 있고 `await` 없음.
|
|
- **원인**: PointBuilder 관련 메서드, HC900Crawler에서는 미사용.
|
|
|
|
### 6. Hc900DbContext.cs:1342 - `PreviewRealtimeBuildAsync()`
|
|
|
|
```csharp
|
|
public async Task<PointBuilderPreviewResult> PreviewRealtimeBuildAsync(
|
|
IEnumerable<(string GroupKey, PointBuilderGroupDto Group)> groups)
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: `async` 키워드만 있고 `await` 없음.
|
|
- **원인**: PointBuilder 관련 메서드, HC900Crawler에서는 미사용.
|
|
|
|
### 7. Hc900DbContext.cs:1726 - `QueryMasterAsync()`
|
|
|
|
```csharp
|
|
public async Task<NodeMapQueryResult> QueryMasterAsync(
|
|
int? minLevel, int? maxLevel, string? nodeClass,
|
|
IEnumerable<string>? names, string? nodeId, string? dataType,
|
|
int limit, int offset)
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: `async` 키워드만 있고 `await` 없음.
|
|
- **원인**: OPC UA 노드 맵 쿼리 메서드, HC900Crawler에서는 미사용.
|
|
|
|
### 8. Hc900DbContext.cs:1735 - `GetRealtimeNodeDataTypesAsync()`
|
|
|
|
```csharp
|
|
public async Task<IReadOnlyDictionary<string, string>> GetRealtimeNodeDataTypesAsync()
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
- **문제**: `async` 키워드만 있고 `await` 없음.
|
|
- **원인**: OPC UA 관련 메서드, HC900Crawler에서는 미사용.
|
|
|
|
## 수정 방안
|
|
|
|
### 권장: `async` 키워드 제거 (가장 단순하고 명확)
|
|
|
|
`throw`만 하는 스텁 메서드는 `async`가 필요 없습니다. `async` 키워드를 제거하고 `Task`를 직접 반환하면 됩니다.
|
|
|
|
```csharp
|
|
// 수정 전
|
|
public async Task<int> ClearRecordsAsync()
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
|
|
// 수정 후
|
|
public Task<int> ClearRecordsAsync()
|
|
{
|
|
throw new NotImplementedException("OPC UA method not applicable in HC900Crawler");
|
|
}
|
|
```
|
|
|
|
`Task.FromResult()`로 감쌀 필요도 없습니다. `throw`는 즉시 예외를 발생시키므로 `Task` 래핑이 필요 없으며, 호출 측에서 `await` 시에도 정상적으로 예외가 전파됩니다.
|
|
|
|
### 대안: `async` 유지 + `Task.FromResult()` 사용 (불필요한 오버헤드)
|
|
|
|
```csharp
|
|
public async Task<int> ClearRecordsAsync()
|
|
{
|
|
return Task.FromResult(0);
|
|
}
|
|
```
|
|
|
|
- **비추천**: 불필요한 상태 기계(state machine) 생성 오버헤드 발생.
|
|
- `throw`만 하는 메서드에 `async`는 전혀 의미가 없음.
|
|
|
|
## 수정 대상 파일
|
|
|
|
- `src/Infrastructure/Database/Hc900DbContext.cs`
|
|
- 라인 1306, 1311, 1319, 1324, 1337, 1342, 1726, 1735
|
|
- 총 8개 메서드에서 `async` 키워드 제거
|
|
|
|
## 수정 후 기대 효과
|
|
|
|
1. CS1998 경고 8건 모두 제거
|
|
2. 불필요한 async 상태 기계 생성 오버헤드 제거 (매 호출마다 ~수십 바이트 스택 할당 제거)
|
|
3. 코드 가독성 향상 (async가 진짜 비동기 연산이 있는 곳에만 사용됨)
|