首页 > 解决方案 > 如何在两个方法执行之间进行延迟?

问题描述

我使用 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

标签: c#async-await

解决方案


更新

我的错,我没有看到UI 线程上需要等待。现在我在这里更新了我的答案,如果方法是同步的,则称这是不可能的,并且 UI 不应该冻结。

只有一个 UI 线程。如果它被同步方法阻止。用户界面肯定会冻结。

我推荐make DoPerformCommandOnClientasync,这样可以正确等待任务,并且可以在等待期间返回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 线程。


推荐阅读