2014-11-03 58 views
5

如何更好地爲同步方法創建異步包裝器?創建異步包裝器的方法

// sync method 
public void LongOperation() 
{ 
    //code... 
} 


// versions of wrapper 
public async Task LongOpertionWrapperAsyncV1() 
{ 
    var task = Task.Factory.StartNew(LongOperation); 
    await task.ConfigureAwait(false); 
} 

public Task LongOpertionWrapperAsyncV2() 
{ 
    var task = Task.Factory.StartNew(LongOperation); 
    task.ConfigureAwait(false); 
    return task; 
} 

儘管兩個版本的使用沒有區別。

async Task Executor() 
{ 
    await LongOpertionWrapperAsyncV1(); 
    await LongOpertionWrapperAsyncV2(); 
} 

對於返回值(任務<Ť>)方法中,我使用的第一個版本。

但我想知道您的意見。

這些版本之間有一個普遍的區別嗎?

+2

備案:http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx – ken2k 2014-11-03 15:41:25

+0

順便說一句,這個:'task.ConfigureAwait(false);'不做*什麼*。 'ConfigureAwait()'*返回一個awaiter,如果你忽略返回值,它不會有任何效果。 – svick 2014-11-06 14:52:17

回答

4

你應該用 「像」 V2:

public Task LongOpertionWrapperAsyncV2() 
{ 
    return Task.Run(LongOperation); 
} 

async Task Executor() 
{ 
    await LongOpertionWrapperAsyncV2().ConfigureAwait(false); 
} 

這樣可以節省你一個上下文切換相比V1。只要你不需要「等待另一個操作」,async-Task就是方法中的最後一個操作,你可以返回任務而不是等待它,並把await留給調用者(它也可以或不可以添加ConfigureAwait)。

Task.Factory.StartNew只有在您需要提供​​(如建議的HPT)時才需要。

UPDATE:
斯蒂芬已經meantioned:有極少數的情況下,你應該做的async over sync(但也有)。所以在執行這樣的事情之前,想想你正在做什麼。簡化說:如果它是CPU綁定的工作不要做,如果它是某種「等待IO」MAYBE做它。
我們有一個案例,我們在這裏開發了一個「近乎異步」的庫,用來控制不同的硬件設備。還有整個「通用庫」是異步的,但一些低級別的設備驅動程序和/或訪問庫不支持async等最底層,我們做這樣的事情:

public async Task<byte[]> ReadAsync(int length) 
{ 
    return Task.Run(() => hwDevice.Read(length)); 
} 

hwDevice.Read確實還鎖定線程,但不是CPU,所以UI在這段時間內是響應的,我們正在等待IO(在「真實生活」中,它也是一些取消和錯誤處理邏輯)。

14

Neither solution is correct。最好的答案是而不是公開同步代碼的異步方法。我更多地進入「爲什麼」on my blog

如果您的代碼是異步的,則使用asyncawait。如果不是,那就不要。應該由呼叫者決定如何調用代碼(例如,使用Task.Run)。

+0

是否有正確的方法來包裝應該異步異步的同步方法?即假設你有同步方法,GetDatabaseData();由於數據庫調用是I/O綁定,有沒有辦法使這種異步? – Mackers 2016-09-14 20:08:28

+1

@Mackers:不可以。如果方法不是異步的,那麼就沒有辦法使它「異步」(除非你修改實現,當然)。 – 2016-09-14 21:10:24

+0

@StephenCleary我讀過你的「不要在異步塊」的帖子。如果我想做一個異步方法的同步包裝呢?我應該在我的同步方法(異步的包裝)中使用'ConfigureAwait'嗎? – lll 2017-05-13 15:51:00