繁体   English   中英

异步方法说明

[英]Async methods Explanation

好吧,所以我是异步,等待和任务的新手,所以我玩了一下,然后用谷歌搜索,但是我还不确定它是如何工作的以及应该如何实现的,所以让我从给出代码开始

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
    }
}

上面的代码只是对我如何设计类的“简化”说明,它不仅限于此,还应为您提供一个想法。 现在我目前在wpf和Xamarin中使用它,并且效果很好,但是在Xamarin中,我开始使用Task而不是Thread,因为PCL仅包含Task,这使我和Idea可以使用上述模式重写部分代码(这部分是完成)但是我不完全理解async / await,使用上面的代码将是更好的使用方法,或者是否有更好的方法

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

首先,考虑一次要执行的简单列表函数:

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

现在,当您添加等待时:

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

考虑它的一个好方法是,如果编译器实际上为您生成了此Psuedo代码:

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();
}

请记住,这是不是真的发生了什么,只是一个很好的方式来包装它周围你的头。

看来您正在寻找对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时该方法实际发生的情况。

等待=此时执行停止,并且程序将执行其他操作,直到等待任务完成。 然后,执行将继续在等待行下方。

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

任务t = blaAsync =立即启动(您可以稍后通过t.wait等待)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM