A
A
Andrey Eskov2018-12-01 16:37:33
.NET
Andrey Eskov, 2018-12-01 16:37:33

How to run a Task for a specific time?

Good evening everyone.
Due to lack of experience, I can not solve the problem. I will be grateful for help.
There is a class and a method that receives the name of the server through the socket Server.GetServerName();
Now when the server is active, the data is received quickly and well, without a glitch. But if the server slows down or is loaded or is generally disabled, then the application completely hangs, or the answer does not come, or the socket does not fall off.
I understand that you need to run it through Task.Run(() => Server.GetServerName()); And also asynchronously.
But if so, then the thread will hang until the socket falls off, or even indefinitely.
Tell me, you can somehow use Task and await / async to make sure that if Server.GetServerName () does not return a string within 30 seconds, we stop and delete the task.
I want to write a wrapper for Server.GetServerName () that will not hang up the application, and will also return an empty string or throw an exception if it could not get the data. But experience and / or brains are not enough.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
B
basrach, 2018-12-02
@taurus2790

string serverName = null;
  var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
  Task.Run(() => serverName = Server.GetServerName(), cancellationTokenSource.Token);

In this case, the call to Server.GetServerName() will occur in the background and will not block the main thread. Theoretically, the task will be canceled after 30 seconds. But in fact, the task will hang in the network waiting for a response until the response arrives, and only after the response arrives will a free thread from the pool be selected, which will take this task to continue execution and possibly interrupt it, but it is possible that and will not interrupt.
If you absolutely want the task not to run after 30 seconds, then you need to rewrite the GetServerName() method as follows:
public string GetServerName(CancellationToken cancellationToken)
{
  // здесь непосредственно вызов по сети
  
  cancellationToken.ThrowIfCancellationRequested();
}

or:
public string GetServerName(CancellationToken cancellationToken)
{
  // здесь непосредственно вызов по сети

  if (cancellationToken.IsCancellationRequested)
  {
    return;
  }
}

and, accordingly, its call will look like this in this case:
Server.GetServerName(cancellationTokenSource.Token)

T
tex0, 2018-12-01
@tex0

Tyts

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question