延迟API操作

4

我正在为我的软件编写API,它有很多接口,而我的软件只是继承了它们。
我希望API的用户可以在X毫秒后执行某些操作,就像这样:

public void PerformAction(Action action, int delay)
{
   Task.Run(async delegate
   {
       await Task.Delay(delai);
       Form.BeginInvoke(action);
       // I invoke on the Form because I think its better that the action executes in my main thread, which is the same as my form's thread
   });
}

现在我知道任务就像一个新的线程,但我想知道这对我的软件有没有不好的影响?是否有其他更好的方式?
这个方法会被频繁执行,所以我不知道这种方法是好还是坏。


3
为什么不直接把你的 PerformAction 改成 async Task,然后只需调用 await Task.Delay(); action(); 就可以了?启动一个任务只是为了让它睡眠,然后尝试回到UI线程非常复杂。 - Panagiotis Kanavos
因为我需要API用户这样使用它:Client.PerformAction(TheirAction,1000); 因为并非每个用户都知道任务/异步的用法。 - Haytam
1
实际上它们确实有异步方法,因为这个框架本身就充满了异步方法。如果你不了解Tasks,就无法编程.NET。 - Panagiotis Kanavos
2个回答

6
您不应该为此创建一个新的任务,而是可以将这个方法作为一个任务,例如:
public async Task PerformAction(Action action, int delay)
{
   await Task.Delay(delay);
   action(); //this way you don't have to invoke the UI thread since you are already on it
}

然后就可以像这样简单使用它:

public async void Butto1_Click(object sender, EventArgs e)
{
    await PerformAction(() => MessageBox.Show("Hello world"), 500);
}

如果他们在新线程上执行了该方法,会怎样? - Haytam
@HaitamZanid 在这种情况下,您需要首先调用UI线程。您还可以解释如何使用API,并在用户面临异常时让API的用户阅读它。 - Camilo Terevinto
那么 Form.BeginInvoke(action); 是一个不好的想法吗? - Haytam
@HaitamZanid 这不是一个坏主意,只是如果API被正确使用的话就是多余的。当然,只有在操作将与UI对象交互时才需要这样做。如果操作不会使用UI对象,那么就没有必要调用UI线程。 - Camilo Terevinto
我的软件不是为那些精通C#的用户设计的,因此我更喜欢处理一些异常情况,使其变得更加简单^^ - Haytam

0
    public async Task PerformAction(Action action, int delay)
    {
        await Task.Delay(delay);
        action();
    }

"async void" 是一个非常糟糕的想法,因为它无法被等待和处理异常。它只应该用于事件处理程序(或类似具有“fire-and-forget”语义的方法)。 - Panagiotis Kanavos
@PanagiotisKanavos 大体上同意,但在用户界面事件中使用是可以的。cFrozenDeath 给出了更好的答案。 - Stephen Zeng
不,这样做是不行的。你的代码可能永远不会执行,或者 "action()" 可能会抛出异常而未被检测到。 - Panagiotis Kanavos
@PanagiotisKanavos 你是正确的。帖子已更新。可以请您取消负评吗? - Stephen Zeng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接