Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将时基轮询与等待任务相结合_C#_Timer_Async Await_Polling - Fatal编程技术网

C# 如何将时基轮询与等待任务相结合

C# 如何将时基轮询与等待任务相结合,c#,timer,async-await,polling,C#,Timer,Async Await,Polling,我已经实现了一个基于计时器的轮询工作程序。例如,您可以想到客户端的TryConnect——我调用TryConnect,它最终将在一段时间内连接。它处理多个线程,如果连接已在进程中,则所有后续的TryConnect将立即返回,而无需任何额外操作。在内部,我只是创建一个计时器,每隔一段时间我尝试连接——如果连接失败,我会再试一次。等等 小缺点是它是“fire&forget”模式,现在我想将它与“async/await”模式结合起来,即调用: client.TryConnect(); // retur

我已经实现了一个基于计时器的轮询工作程序。例如,您可以想到客户端的
TryConnect
——我调用
TryConnect
,它最终将在一段时间内连接。它处理多个线程,如果连接已在进程中,则所有后续的
TryConnect
将立即返回,而无需任何额外操作。在内部,我只是创建一个计时器,每隔一段时间我尝试连接——如果连接失败,我会再试一次。等等

小缺点是它是“fire&forget”模式,现在我想将它与“async/await”模式结合起来,即调用:

client.TryConnect(); // returns immediately
// cannot tell if I am connected at this point
我想这样称呼它:

await client.TryConnect();
// I am connected for sure
如何更改实现以支持“异步/等待”?我正在考虑创建空的
任务
(仅用于
等待
),然后使用
FromResult
完成它,但此方法创建一个新任务,它不会完成给定实例

作为记录,当前实现如下所示(只是代码的草图):

由于缺乏良好的沟通,因此无法提供任何具体的建议。根据您所写的内容,您可能正在寻找的是
TaskCompletionSource
。例如:

private TaskCompletionSource<bool> _tcs;

public async Task TryConnect()
{
   if (/* no connection exists */)
   {
     if (_tcs == null)
     {
       this.timer = new Timer(_ => tryConnect(),null,-1,-1);
       this.timer.Change(0,-1); 
       _tcs = new TaskCompletionSource<bool>();
     }

     await _tcs.Task;
   }
}

private void tryConnect()
{
   if (/*connection failed*/)
     this.timer.Change(interval,-1);
   else
   {
     _tcs.SetResult(true);
     _tcs = null;
     this.timer = null;
   }
}
private TaskCompletionSource<bool> _tcs;

public async Task TryConnect()
{
   if (/* no connection exists */)
   {
     if (_tcs == null)
     {
       this.timer = new Timer(_ => tryConnect(),null,-1,-1);
       this.timer.Change(0,-1); 
       _tcs = new TaskCompletionSource<bool>();
     }

     await _tcs.Task;
   }
}

private void tryConnect()
{
   if (/*connection failed*/)
     this.timer.Change(interval,-1);
   else
   {
     _tcs.SetResult(true);
     _tcs = null;
     this.timer = null;
   }
}