处理任务超时和异常



我在WPF应用程序中的C#(.NET Framework 4.8(中有一个特定的Func<bool> func,并希望它被执行。我想要一个接受这种Funcs并返回bool的方法。

  1. 它应该在后台运行,而不是阻塞UI线程。可能我需要Task<bool>
  2. 如果它花费的时间超过某个超时限制,则应取消它并返回false
  3. 程序应等待任务完成,但如果任务已提前完成,则不应等待完整的时间限制
  4. 如果遇到错误,则应打印错误消息,取消任务,并且程序不应崩溃或冻结

有什么复杂的方法可以满足这些要求吗?如果这是更好的解决方案,则该解决方案也可以使用Task<bool>而不是Func<bool>。它应该以类似的方式使用:

public class Program
{
    public static void Main(string[] args)
    {
        bool result = ExecuteFuncWithTimeLimit(3000, () =>
        {
            // some code here of a specific task / function
        });
    }
    public static bool ExecuteFuncWithTimeLimit(int timeLimit_milliseconds, Func<bool> codeBlock)
    {
        // run func/task in background so GUI is not freezed
        // if completed in time: return result of codeBlock
        // if calceled due to time limit: return false
        // if error occured: print error message and return false
    }
}

经过一段时间的实验,我通过中止线程找到了一个解决方案。我知道它不推荐,但它工作得很好,为我做它的工作。

public class Program
{
    public static void Main(string[] args)
    {
        Task.Run(() =>
        {
            if (!ExecuteTaskWithTimeLimit(1000, () => { return DoStuff1(); })) return;
            if (!ExecuteTaskWithTimeLimit(1000, () => { return DoStuff2(); })) return;
            // ...
        });
    }
    public static bool ExecuteTaskWithTimeLimit(int timeLimit_milliseconds, Func<bool> codeBlock)
    {
        Thread thread = null;
        Exception exception = null;
        // do work
        Task<bool> task = Task<bool>.Factory.StartNew(() =>
        {
            thread = Thread.CurrentThread;
            try
            {
                return codeBlock();
            }
            catch (Exception e)
            {
                exception = e;
                return false;
            }
        });
        // wait for the task to complete or the maximum allowed time
        task.Wait(timeLimit_milliseconds);
        // if task is canceled: show message and return false
        if (!task.IsCompleted && thread != null && thread.IsAlive)
        {
            ConsoleWriteLine("Task cancled because it timed out after " + timeLimit_milliseconds + "ms.");
            thread.Abort();
            return false;
        }
        // if error occured: show message and return false
        if (exception != null)
        {
            MessageBox.Show(exception.Message, "Exeption", MessageBoxButton.OK, MessageBoxImage.Error);
            return false;
        }
        // if task has no error and is not canceled: return its return value
        return task.Result;
    }
}

相关内容

  • 没有找到相关文章

最新更新