Async methods Explanation

时间:2015-07-16 11:44:58

标签: c# wpf asynchronous async-await task-parallel-library

Ok so I am new to async, await and Task so I played around a bit and googled but I am not quite sure yet how it works and how it is supposed to be implemented So let me start by giving my code

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

The above code is only a 'simplified' explanation of how I designed my classes, there is more to it than just this but it should give you an Idea. Now I am currently using this in wpf & Xamarin and it works well but in Xamarin I started to use Task and not Thread because PCL has only Task in, this gave me and Idea to rewrite parts of code using the pattern above (which is partially completed) BUT I do not understand the async/await completely, using the above code which will be the better approach to use, or is there a better approach to take

3 个答案:

答案 0 :(得分:2)

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

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

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

现在,当你添加await:

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

请记住,这不是真的正在发生的事情,只是一种很好的方式来围绕它。

答案 1 :(得分:1)

您似乎正在考虑使用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时实际发生的情况。

答案 2 :(得分:0)

Await =执行在此时停止,程序执行其他操作,直到await任务完成。 然后执行继续在await线下面。

async void =用于事件,不等待。

任务t = blaAsync = INSTANT START(您可以稍后等待t.wait)