我知道使用异步void不是一个好习惯。但是,如果我不想等待长期运行的结果怎么办?
我有一种情况,我需要在数据库中插入一些值并返回结果。但是,我无需等待完成所有插入操作即可返回对象的实例。
如果您看下面的代码,则有一个方法可以初始化DataService。但是在初始化部分,它需要向数据库插入代码描述和标头。我想返回dataService,我不在乎代码说明和标头是否已完成插入。
async Task<DataService> InitializeAsync()
{
_dataService = new DataService();
await _dataService.InsertCodeDescriptionAsync();
await _dataService.InserHeadersAsync();
return _dataService;
}
我认为我可以通过将InsertCodeDescriptionAsync和InsertHeadersAsync更改为异步void函数来实现。但是,根据我阅读的一些文章,这不好。那么在这种情况下最好的办法是什么?
更新: 目标是初始化dataService并在后台进行插入。
答案 0 :(得分:3)
我的建议答案有两个:
简单的答案:如果您不需要等待任务,那就不要等待它。
但是结果将是您的主代码的执行上下文和您未等待的任务的执行上下文将发生分歧,并且如果在您在代码中永远不会知道的任何一种方法中发生异常。我想您调用这两个方法是有原因的,它们会执行您的代码最终需要但并非立即执行的操作?
如果是这样,那么即使您不需要立即完成方法,我还是建议您仍然使用await
。但是,这将确保方法在某个时候完成,并且对性能的影响通常很小,尤其是在多线程方案中,因为这是异步魔术开始的时刻,并在等待时释放了大量CPU时间。
如果要兼顾速度和可靠性,可以执行类似的操作
(DataService, Task) InitializeAsync()
{
_dataService = new DataService();
var t = Task.WhenAll(_dataService.InsertCodeDescriptionAsync(), _dataService.InserHeadersAsync());
return (_dataService, t);
}
这将立即为您提供dataService,而且还提供了一个Task,您可以在需要完成初始化方法时使用它来等待它们完成。
答案 1 :(得分:2)
不要等待您不想等待的任务。像下面这样的东西将为您工作。
Task<DataService> InitializeAsync()
{
_dataService = new DataService();
_dataService.InsertCodeDescriptionAsync();
_dataService.InserHeadersAsync();
return Task.FromResult(_dataService);
}
答案 2 :(得分:-2)
您可以完全摆脱
import numpy as np
from astropy.io import fits
import matplotlib.pyplot as plt
from scipy import interpolate
from tqdm import tqdm
from scipy import ndimage
import peakutils
from scipy.optimize import curve_fit
def gauss(x, x0, amp, wid):
return amp * np.exp( -((x - x0)/wid)**2)
def multi_gauss(x, *params):
y = np.zeros_like(x)
for i in range(0, len(params), 3):
x0, amp, wid = params[i:i+3]
y = y + gauss(x, x0, amp, wid)
return y
neon = fits.getdata(data_directory + wave_filename + '.fits')
neon_sp = np.mean(neon, axis= 0)
n_pix = len(neon_sp)
peaks_index = peakutils.peak.indexes(neon_sp, thres=0.05, min_dist=2)
### peals around the brightest peak
bright_index = peaks_index[np.argmax(neon_sp[peaks_index])]
delta_pix = 20
ind_min = bright_index - delta_pix
ind_max = bright_index + delta_pix
peak_select = peaks_index[np.where((peaks_index > ind_min) & (peaks_index < ind_max))]
peak_select_sort = peak_select[np.argsort(-neon_sp[peak_select])]
if peak_select_sort[1] > peak_select_sort[0] :
ind_max = bright_index + 40
else :
ind_min = bright_index - 40
peak_select = peaks_index[np.where((peaks_index > ind_min) & (peaks_index < ind_max))]
peak_select_sort = peak_select[np.argsort(-neon_sp[peak_select])]
plt.figure(num=0)
plt.clf()
plt.plot(neon_sp)
plt.plot(peaks_index,neon_sp[peaks_index], 'r+')
plt.plot(peak_select,neon_sp[peak_select], 'ro')
### Gaussian fit
x = np.arange(n_pix)
xx = np.arange(0, n_pix, .1)
n_peak = 4
bright_index_fit = np.zeros(n_peak)
for i in range(n_peak):
p = peak_select_sort[i]
guess = [p, neon_sp[p], .5]
popt, pcov = curve_fit(gauss, x, neon_sp, p0=guess)
fit = gauss(xx, *popt)
bright_index_fit[i] = popt[0]
plt.plot(xx,fit, '--')
bright_wave = [703.2, 724.5, 693.0, 743.9]
和async
:
await
这样,您可以避免任何编译器警告,并可以将忽略任务结果的意图传达给代码的未来维护者。