C# 正确使用异步/等待和任务
我正在尝试学习这些“新”关键字,并尝试实现一个简单的异步udp服务器C# 正确使用异步/等待和任务,c#,visual-studio-2012,asynchronous,task,C#,Visual Studio 2012,Asynchronous,Task,我正在尝试学习这些“新”关键字,并尝试实现一个简单的异步udp服务器 public class UdpServerSync { private CancellationTokenSource _cts; private CancellationToken _token; private UdpClient _client; public void Start() { Console.WriteLine("Start server");
public class UdpServerSync
{
private CancellationTokenSource _cts;
private CancellationToken _token;
private UdpClient _client;
public void Start()
{
Console.WriteLine("Start server");
_cts = new CancellationTokenSource();
_token = _cts.Token;
var ipAddress = IPAddress.Parse("192.168.0.25");
var ip = new IPEndPoint(ipAddress, 7070);
try
{
Task.Run(async () =>
{
using (_client = new UdpClient(ip))
{
while (!_token.IsCancellationRequested)
{
var receivedData = await _client.ReceiveAsync();
var msg = Encoding.ASCII.GetString(receivedData.Buffer);
// Process request e.g ProcessRequest(msg);
Console.WriteLine(msg);
}
}
}, _token).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public void Stop()
{
Console.WriteLine("Stop server");
if (_cts != null) _cts.Cancel();
}
然后像这样使用它(用于测试目的):
上面的代码只是一个概念证明,它不是关于代码审查。简单的udp服务器是指一个带有udpclient的while循环,监听udp消息并将其写入控制台-无需处理或错误处理
之所以使用Task.Delay,只是因为它证明了调用服务器的start()和stop()方法的概念
缩小我的问题范围:
1) 如果我要从WPF应用程序的开始按钮调用Start()和Stop()方法,我应该使用server.Start()还是Task.Run?我不想等待呼叫,因为无法知道用户希望服务器启动多长时间
2) 在服务器代码“ProcessRequest(msg)”中,如果这是另一个库中的void方法,我应该使用Task.Run()来执行它以避免服务器线程被阻塞,还是有更好的方法
3) 当我们执行async/await时,await语句中的代码是否在线程池中的新线程中执行
4) 我可以指定UdpServer是一个长时间运行的进程,还是与线程池无关
希望我的问题现在更清楚,谢谢大家:)
1) 如果我要从WPF应用程序的开始按钮调用Start()和Stop()方法,我应该使用server.Start()还是Task.Run
使用您现在拥有的代码,您只需调用Start
(调用Task.Run
)。IMO不需要调用Task.Run
。调用ConfigureAwait
肯定不需要,因为没有await
进行配置
我不想等待呼叫,因为无法知道用户希望服务器启动多长时间
但您可能确实想知道任何异常。因此,请考虑如何处理这些异常。一种解决方案是将返回的任务
保存为属性。或者,您可以等待它(请记住,它运行“多长时间”无关紧要,因为它是异步等待)
2) 在服务器代码“ProcessRequest(msg)”中,如果这是另一个库中的void方法,我应该使用Task.Run()来执行它以避免服务器线程被阻塞,还是有更好的方法
没有“服务器线程”。但是如果<代码>进程请求< /> >需要很长时间,那么您可能需要考虑使用<代码>任务。运行< /COD>使您的代码在处理该代码时接受下一个请求。
3) 当我们执行async/await时,await语句中的代码是否在线程池中的新线程中执行
没有。我在我的博客上有一个更详细的说明
4) 我可以指定UdpServer是一个长时间运行的进程,还是与线程池无关
没关系。你的问题太宽泛了;尽量说得更具体些。另外,如果这是一个代码审查,你应该把它张贴在你真正想做的事情上?代码是否符合您的要求?这里有什么问题?但是不,你现在做的看起来不对。等待一段时间并希望任务完成是不对的。您应该为
服务器提供一种机制,告诉您何时完成。你可以从一开始就返回任务,这样你就可以给它附加一个延续。你似乎在做正常的线程。你的方法应该是异步的,调用它们应该等待(如果你返回了一些东西的话)。我建议您从更简单的方法开始,比如使用HttpClient
异步检索网页
var server = new UdpServerSync();
server.Start();
await Task.Delay(5000);
server.Stop();