正在等待如何知道我的异步方法?

时间:2014-06-01 02:29:14

标签: c# async-await

是否可以知道我的方法是否使用'await'关键字进行调用?

例如;方法MyAsync()想知道是否等待它。

public void CallForBackground()
{
    MyAsync();
}

public async void CallAsync()
{
    bool result = await MyAsync();
}

public Task<bool> MyAsync()
{
    return Task.Run(() =>
    {
    //do something endlessly if its being called without 'await', but how do I know the caller is 'await'ing or not?
    //do something only once if its being called with 'await', but how do I know the caller is 'await'ing or not?


    return true;
    });
}

已编辑:添加了一个场景,我想知道是否使用'await'调用MyAsync();

1)假设MyAsync()使用TCP连接到远程服务器。

2)MyAsync()是异步的,等待。

3)假设UserA想要异步连接到远程服务器,一旦完成,他/她想知道在继续他的过程之前是否成功。类似于CallAsync()方法实现的东西。

4)UserB想要触发MyAsync()方法,而不是等待它完成。在这种情况下,UserB在向远程服务器发送消息之前不关心它是否已连接。类似于CallForBackground()方法实现的东西。

因此,对于UserA(等待),MyAsync()方法将尝试一次并返回状态。但对于UserB(不等待),方法将继续尝试。对于这个逻辑,MyAsync()需要知道它是否正在等待。我们如何实现这一目标?

3 个答案:

答案 0 :(得分:6)

  1. 您不应该async方法返回void。只是不要这样做,除非你确定这是你需要的(但很可能你不需要!)。

  2. async是一个实现细节,它允许您使用await以更简单,更方便的方式编写方法体,并让编译器为您准备所有必要的回调等。

  3. 您无法通过Task返回来判断人们在做什么。

答案 1 :(得分:2)

  

我们如何实现这一目标?

你不*。根据用户对其返回值的作用,方法的行为不应该有所不同。如果您想要有两种不同的行为,请在方法中添加bool参数,或者更好的是,为此设置两种不同的方法。


*实际上有一种方法可以确定您的方法是否为await。但这很复杂(它涉及使用自定义等待者而不是Task),我不认为这是正确的解决方案。

答案 2 :(得分:0)

显然,您希望您的操作取决于调用过程的快速性。如果调用进程真的很快,它会在你检查它是否等待之前等待。如果它有点慢,它在你检查之前还没有开始等待。

您确定要让您的功能取决于呼叫者的快速性吗?

如果你知道某人是否会开始等待你的结果,那会不会更好?在这种情况下,您的流程的启动者可以使用参数指示他是否会在不久的将来等待您的回答。

如果您的流程的启动者还不知道他将来是否会等待您的回答,他可以使用CancellationToken取消您的任务,一旦他决定永远不等待您的回答。

例如:   - 开始10分钟的过程。初学者认为他将开始等待,比如五分钟。在那之前,他有更好的事情要做。   - 在起动器开始等待之前,操作员决定停止程序。所以首发人员知道他永远不会开始等待。他使用CancellationToken表示他永远不会等待结果。    - 该过程定期检查cancellationToken,看看是否仍有预期是否会等待。

public async Task<bool> MyAsync(CancellationToken token)
{
    return Task.Run(() =>
    {
        while (!token.IsCancellationRequested)
        {   // we can still expect that in the near future someone will await
            // act accordingly
        }
        else
        {   // we know for sure that no one will await for the result anymore
            // act accordingly
         }
    });
}