c# - 如何在两个方法执行之间进行延迟?
问题描述
我使用 async/await 在方法执行之间进行延迟。
有一个代码
public bool DoPerformCommandOnClient(string commandStr, bool isOnPath, string folderPath, string ext, string doneMessage, string excludeString)
{
Task.Run(() => DoOpenProgressBarWindowWithDelay(2000));
return GetLogic().PerformCommandOnClient(commandStr, isOnPath, folderPath, ext, doneMessage, excludeString);
}
public async void DoOpenProgressBarWindowWithDelay(int delay)
{
BeginInvoke((Action)(() => {
DoOpenProgressBarWindow();
}));
await Task.Delay(delay);
}
所以,我想执行DoPerformCommandOnClient
方法,然后在 2 秒延迟后执行下一行
return GetLogic().PerformCommandOnClient(commandStr, isOnPath, folderPath, ext, doneMessage, excludeString);
但相反,此方法会DoPerformCommandOnClient
立即执行。
然后我尝试Thread.Sleep(2000)
在两行之间添加
public bool DoPerformCommandOnClient(string commandStr, bool isOnPath, string folderPath, string ext, string doneMessage, string excludeString)
{
DoOpenProgressBarWindow();
Thread.Sleep(2000);
return GetLogic().PerformCommandOnClient(commandStr, isOnPath, folderPath, ext, doneMessage, excludeString);
}
但是这种方法会停止我的 UI,我不需要停止我的 UI。
那么,问题是如何在两种方法之间进行延迟?
编辑
现在代码看起来像这样
public bool DoPerformCommandOnClient(string commandStr, bool isOnPath, string folderPath, string ext, string doneMessage, string excludeString)
{
Task.Run(() => DoOpenProgressBarWindowWithDelay(2000)).Wait();
return GetLogic().PerformCommandOnClient(commandStr, isOnPath, folderPath, ext, doneMessage, excludeString);
}
public async void DoOpenProgressBarWindowWithDelay(int delay)
{
BeginInvoke((Action)(() => {
DoOpenProgressBarWindow();
}));
await Task.Delay(delay).ConfigureAwait(false);
}
编辑2
现在代码看起来像这样
public async Task<bool> DoPerformCommandOnClient(string commandStr, bool isOnPath, string folderPath, string ext, string doneMessage, string excludeString)
{
await DoOpenProgressBarWindowWithDelay(2000).ConfigureAwait(false);
return GetLogic().PerformCommandOnClient(commandStr, isOnPath, folderPath, ext, doneMessage, excludeString);
}
public async Task<bool> DoOpenProgressBarWindowWithDelay(int delay)
{
BeginInvoke((Action)(() =>
{
DoOpenProgressBarWindow();
}));
await Task.Delay(delay).ConfigureAwait(false);
return true;
}
编辑3
public async Task<bool> DoPerformCommandOnClient(string commandStr, bool isOnPath, string folderPath, string ext, string doneMessage, string excludeString)
{
await DoOpenProgressBarWindowWithDelay(2000).ConfigureAwait(false);
return GetLogic().PerformCommandOnClient(commandStr, isOnPath, folderPath, ext, doneMessage, excludeString);
}
public async Task DoOpenProgressBarWindowWithDelay(int delay)
{
BeginInvoke((Action)(() =>
{
DoOpenProgressBarWindow();
}));
await Task.Delay(delay).ConfigureAwait(false);
}
有一种方法我如何调用此方法
if (!m_MyManagerMainForm.DoPerformCommandOnClient(cmd1, true, sourcePath, "bmp", "ColorImageDone", "_M"))
{
RestoreGUIFromCalibration();
return;
}
但它不起作用,它说我不能隐式转换Task<bool> to bool
解决方案
更新
我的错,我没有看到UI 线程上需要等待。现在我在这里更新了我的答案,如果方法是同步的,则称这是不可能的,并且 UI 不应该冻结。
只有一个 UI 线程。如果它被同步方法阻止。用户界面肯定会冻结。
我推荐make DoPerformCommandOnClient
async,这样可以正确等待任务,并且可以在等待期间返回UI线程:
public async Task<bool> DoPerformCommandOnClient(string commandStr, bool isOnPath, string folderPath, string ext, string doneMessage, string excludeString)
{
await Task.Run(() => DoOpenProgressBarWindowWithDelay(2000));
return GetLogic().PerformCommandOnClient(commandStr, isOnPath, folderPath, ext, doneMessage, excludeString);
}
如果方法必须是sync,那么我建议在工作线程上将工作排队到ThreadPool
, ,等待 2 秒并将继续编组回 UI 线程。