异步方法说明

Async methods Explanation

好的,我是 async、await 和 Task 的新手,所以我玩了一下并用谷歌搜索,但我不太确定它是如何工作的以及它应该如何实现 所以让我先给出我的代码

public class MessageQuery
{
    public byte[] Buffer { get; set; }
}

public class MessageQuery<T> : MessageQuery
{
    private SocketLayer _socketLayer;
    private readonly ManualResetEvent _wait = new ManualResetEvent(false);
    public MessageQuery(SocketLayer socketLayer)
    {
        this._socketLayer = socketLayer;
    }

    public Task<T> Execute()
    {
        _wait.Reset();//Set the wait
        var task = new Task<T>(SendAndWait);
        task.Start();
        return task;
    }

    private T SendAndWait()
    {
        _socketLayer.ExecuteQuery(this);
        _wait.WaitOne();
        //Deserialize recieved bytes to T
        return default(T);
    }

}

public class SocketLayer
{
    public MessageQuery<T> BuildTask<T>(/*some parameters*/)
    {
        //Build the message query from all parameters

        return new MessageQuery<T>(this);
    }


    public void ExecuteQuery(MessageQuery query)
    {
        //Using Sockets send Buffer
        //Another Thread will listen and receive buffers, with using SequenceId's it will notify the correct MessageQuery to be completed with the result
    }
}

public class GlobalAccess
{
    readonly SocketLayer _layer = new SocketLayer();
    public Task<List<Client>> LoadedClients { get; set; }
    public Task<List<Client>> GetAllClients()
    {
        if (LoadedClients != null)
        {
            var task = _layer.BuildTask<List<Client>>();
            LoadedClients = task.Execute();
        }
        return LoadedClients;
    }
}


public class SomeForm
{
    readonly GlobalAccess _access = new GlobalAccess();

    //Approach I am not using currently
    async void Button_whateverClickWithAsync(/*parameters*/)
    {
        var clients = await _access.GetAllClients();
        //Do whatever
    }

    //Approach I am using currently
    void Button_whateverClickWithoutAsync(/*parameters*/)
    {
        _access.GetAllClients().ContinueWith(HandleResult);
        //Do whatever
    }

    private void HandleResult(Task<List<Client>> x)
    {
        //Using Dispatcher to Do whatever
    }
}

以上代码只是 'simplified' 对我如何设计我的 类 的解释,不仅如此,它还应该给你一个想法。 现在我目前在 wpf 和 Xamarin 中使用它并且它运行良好但是在 Xamarin 中我开始使用 Task 而不是 Thread 因为 PCL 只有 Task in,这让我和 Idea 使用上面的模式重写部分代码(部分完成)但我不完全理解 async/await,使用上面的代码将是更好的使用方法,或者是否有更好的方法来采用

Await = 执行在此时停止,您的程序会做其他事情,直到 await 任务完成。 然后执行在等待线的正下方继续。

async void = 对于事件,无需等待。

任务 t = blaAsync = 即时启动(您可以稍后使用 t.wait)

您似乎正在考虑使用 ContinueWith 与使用 async-await.

的显式延续

我绝对更喜欢后者,它会导致更简洁的代码。它有效地允许您 运行 异步代码,同时将其视为同步代码,这使您尝试做的事情更加清晰:

async void Button_whateverClickWithAsync(/*parameters*/)
{
    var clients = await _access.GetAllClients();
    // Here, you execute the rest of your code as if
    // running synchronously.
}

void ButtonClick(/*parameters*/)
{
    _access.GetAllClients().ContinueWith(HandleResult);
    // When does the continuation run? What happens if you want
    // to execute this only if the task fails?
}

这确实归结为编码偏好。如果您选择使用 async-await,您应该更多地了解它并了解当方法被标记为 async.

时实际发生了什么

我发现 await 的最佳思考方式如下:

首先,想想这个要执行的简单列表函数,一次一个:

DoSomething();
SomethingElse();
OneLastThing();

现在,当您添加 await 时:

await DoSomething();
SomethingElse();
OneLastThing();

一个很好的思考方式,就好像编译器真的为你生成了这个伪代码:

Start Task() => { DoSomething(), OnCompleted = TaskCompletedCallback };

//Once the task has finished, after an unknown amount of time
//call this sort-of auto-generated callbcak
private void TaskCompletedCallback()
{
    SomethingElse();
    OneLastThing();
}

请记住,这不是真正正在发生的事情,只是一种让你的头脑围绕它的好方法。