关于在C#中包装异步方法,我有一个奇怪的行为.
很难删除我的代码中有这种奇怪行为的部分,所以我做了一个测试项目来调查行为,这就是我发现的.
我有一个测试类,它有一个异步方法,它只是另一个异步方法的包装器:(在我的原始代码中,它是一个包含2个对象的包装类,它有包装方法)
public class Test
{
public async Task Delay()
{
await Task.Delay(1000);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的测试程序中,我从异步事件处理程序运行以下代码:(在我的情况下是Loaded事件,因为我使用的是WPF窗口)
var test = new Test();
await Task.Delay(1000);
await test.Delay();
Task.Delay(1000).Wait();
test.Delay().Wait();
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到最后一行,永不回归.
然后我尝试将测试类更改为以下内容,最后一行有效:
public class Test
{
public Task Delay()
{
return Task.Delay(1000);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么第一种情况不起作用?
我最近和SignalR一起玩了很多,发现服务器/客户端通信非常棒.
然后我想到了一个与我目前正在进行的项目非常相关的场景.
基本思想是通过ping机器在网页上指明服务器当前是否在线.
该过程由第一个用户启动以访问该页面,并且应该在所有客户端断开连接时停止.
到目前为止,我的服务器代码是:
public class PingHub : Hub
{
private static readonly ConcurrentDictionary<string, DateTime> _users = new ConcurrentDictionary<string, DateTime>();
private static bool _isPolling = false;
public override Task OnConnected()
{
_users.TryAdd(Context.ConnectionId, DateTime.Now);
return Clients.All.UserCountChanged(_users.Count);
}
public override Task OnReconnected()
{
_users.AddOrUpdate(Context.ConnectionId, DateTime.Now, (key, value) => value);
return Clients.All.UserCountChanged(_users.Count);
}
public override Task OnDisconnected()
{
DateTime value;
_users.TryRemove(Context.ConnectionId, out value);
return Clients.All.UserCountChanged(_users.Count);
}
public void GetStatus()
{
if (_isPolling)
return;
_isPolling = true;
var ping = new Ping();
do …Run Code Online (Sandbox Code Playgroud)