문제

공통 SQL 데이터베이스 작업 (백업, 복원, 실행 스크립트 등)을 수행하기 위해 C # .NET 4.5 라이브러리를 작성했습니다. 이 라이브러리가 콘솔과 GUI 응용 프로그램에서 사용하기 때문에 각 작업에 대해 동기식 및 비동기 기능을 모두 갖고 싶지 만 모든 곳에서 코드를 복제하고 싶지는 않습니다. 그래서 내가 볼 때, 나는 두 가지 옵션이있다 :

  1. 동기 기능에서 작업을 수행하는 코드를 작성한 다음 즉시 비동기 함수에 대한 작업으로 랩합니다.

    public void BackupDB(string server, string db)  
    {  
        // Do all of the work and long running operation here  
    }
    
    public async Task BackupDBAsync(string server, string db)  
    {  
        await Task.Factory.StartNew(() => BackupDB(server, db)).ConfigureAwait(false);  
    }
    

  2. 비동기 기능에서 작업을 수행하는 코드를 작성하고 .wait () : 를 사용하여 동기 기능에서 호출합니다.

    public async Task BackupDBAsync(string server, string db)  
    {  
        // Do all of the work and long running operation here, asynchronously.  
    }
    
    public void BackupDB(string server, string db)  
    {  
        BackupDBAsync(server, db).Wait(); // Execution will wait here until async function finishes completely.  
    }
    

    는 다른 옵션보다 낫습니다. 하나는 가장 좋은 방법입니까? 또는 다른 (더 나은) 대안이 있습니까?

    나는 그 하나의 경고를 사용하는 것이 async 함수의 모든 기다리시는 명령문이 교착 상태를 피하기 위해 .configureAwait (false)를 사용해야한다는 것입니다 ( in-c"에서 UI에 액세스 할 필요가없는 도서관을 쓰는 이래로 또는 WebContext 나는 그것을 할 수 있도록 안전합니다.

    SQL 라이브러리가 일반적으로 사용할 수있는 동기식 및 비동기 기능도 모두 있으므로 동기화 함수에서 작업을 수행하는 경우 동기화 함수를 호출하고 비동기에서 작업을 수행하는 경우 기능, 비동기 기능을 호출합니다.

    생각 / 제안은 인정 받고 있습니다.

    - 편집 : 나는 또한이 질문을 여기서 MSDN 포럼에서 공식 MS 응답을 시도하고 얻을

도움이 되었습니까?

해결책

이 라이브러리는 콘솔 및 GUI 응용 프로그램 모두 에서이 라이브러리가 사용되므로 각 작업에 대해 동기식 및 비동기 기능을 모두 갖고 싶지 만 모든 곳에서 코드를 복제하고 싶지는 않습니다.

가장 좋은 대답은 다음과 같습니다.하지 마십시오.

스티븐 Toub에는이 주제에 대한 두 가지 우수한 블로그 게시물이 있습니다 :

다른 팁

일부 응용 프로그램이 동기식으로로드 될 데이터와 다른 ASYC가 필요한 것과 비슷한 상황이있었습니다.나는 Dataloader를 호출 한 인터페이스를 만들기로 결정했습니다.

public interface IIMViewModelDL {
    void LoadProjects(AssignProjects callback);
}
.

AssignProjects 콜백은 반환 된 프로젝트 목록을 수행하는 간단한 대리자입니다.

public delegate void AssignProjects(IEnumerable<Project> results);
.

이제이 아름다움은 동기화 또는 비동기에서 렌일링 여부를 알지 못하지 않고 인터페이스로 작업 할 수 있습니다.

세 개의 클래스가 생성됩니다. 하나의 기본, 하나의 동기화 및 하나의 비동기 :

 public abstract class BaseViewModelDL {
    protected IEnumerable<Project> LoadProjects() {
        BaseServiceClient client = new BaseServiceClient();
        return client.Projects();
    }

public class SynchronousViewModelDL : BaseViewModelDL, IIMViewModelDL {
    public void LoadProjects(AssignProjects callback) {
        callback(base.LoadProjects());
    }

public class AsyncIMViewModelDL : BaseViewModelDL, IIMViewModelDL {
    public void LoadProjects(AssignProjects callback) {
        BackgroundWorker loadProjectsAsync = new BackgroundWorker();
        loadProjectsAsync.DoWork += new DoWorkEventHandler(LoadProjectsAsync_DoWork);
        loadProjectsAsync.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LoadProjectsAsync_RunWorkerCompleted);
        loadProjectsAsync.RunWorkerAsync(callback);
    }

void LoadProjectsAsync_DoWork(object sender, DoWorkEventArgs e) {
        var results = new ObservableCollection<Project>(base.LoadProjects());
        e.Result = new object[] { results, e.Argument };
    }

    void LoadProjectsAsync_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        AssignProjects callback = (AssignProjects)((object[])e.Result)[1];
        IEnumerable<Project> results = (IEnumerable<Project>)((object[])e.Result)[0];
        callback(results);
    }
.

이제 응용 프로그램에서 데이터를로드하려는 방법을 결정할 수 있습니다 ... 이것은 IOC 컨테이너를 통해 주입 될 수 있지만 데모 목적으로 하드 코딩 된 것입니다.

private ViewModelDataLoaders.IIMViewModelDL dataLoader = new ViewModelDataLoaders.AsyncIMViewModelDL();
.

이제 호출 코드가 동일하게 보입니다. vastync 또는 sync인지 여부에 대한 현명한 사람은 없습니다.

private void LoadProjects() {
        dataLoader.LoadProjects(
            delegate(IEnumerable<Project> results) {
                Projects = new ObservableCollection<Project>(results);
            });
    }
.

단위 테스트 (동기화), WPF 응용 프로그램 (ASYNC) 및 콘솔 응용 프로그램 (동기화)에 대해 정기적으로 사용합니다.

기다리고 사용하지 않고 비동기로 메소드를 만드는 방법이되는 것은 아닙니다. 비동기를 비동기화하지 않으므로 기다리고 있으면 기다리십시오 (AWAIT에서 실행 된 코드는 비동기식이 일어나는 일이 발생한 다음 나머지 비동기 메소드가 비동기 적으로 수행됩니다). / P>

전형적으로, async 키워드에 의해 수정 된 방법은 적어도 하나의 기다린 표현식 또는 명령문을 포함한다. 이 방법은 첫 번째 기다리는 표현식에 도달 할 때까지 동기식으로 실행됩니다.이 가리키는 작업이 완료 될 때까지 일시 중단됩니다. 그 동안 제어자가 메소드의 발신자에게 반환됩니다. 메서드에 AWAIT Expression 또는 Statement가 포함되어 있지 않으면 동 기적으로 실행됩니다. 컴파일러 경고는 해당 상황이 오류를 나타낼 수 있으므로 기다리지 않는 ASYNC 메소드로 알려줍니다. 자세한 내용은 컴파일러 경고 CS4014를 참조하십시오.

: Async / P>

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top