异步方法说明
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();
}
请记住,这不是真正正在发生的事情,只是一种让你的头脑围绕它的好方法。
好的,我是 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();
}
请记住,这不是真正正在发生的事情,只是一种让你的头脑围绕它的好方法。