gpt4 book ai didi

C# Xamarin Forms - 执行任务,超时

转载 作者:行者123 更新时间:2023-11-30 23:15:03 29 4
gpt4 key购买 nike

像许多其他人一样,我需要编写一个返回任务的函数,并且我希望该任务在一段时间后自动超时。

初始代码如下所示:

class MyClass
{
TaskCompletionSource<string> m_source;

public Task<string> GetDataFromServer()
{
m_source = new TaskCompletionSource<string> ();

// System call I have no visibility into, and that doesn't inherently take any
// sort of timeout or cancellation token
ask_server_for_data_and_when_youve_got_it_call(Callback);

return m_source.Task;
}

protected void Callback(string data);
{
// Got the data!
m_source.TrySetResult(data);
}
}

现在我希望它更智能一些,并在适当的时候自行超时。为此,我有多种选择:

class MyClass
{
TaskCompletionSource<string> m_source;

public Task<string> GetDataFromServer(int timeoutInSeconds)
{
m_source = new TaskCompletionSource<string> ();

ask_server_for_data_and_when_youve_got_it_call(Callback);

// Method #1 to set up the timeout:
CancellationToken ct = new CancellationToken ();
CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource (ct);
cts.CancelAfter (timeoutInSeconds * 1000);
cts.Token.Register(() => m_source.TrySetCancelled());

// Method #2 to set up the timeout:
CancellationTokenSource ct2 = new CancellationTokenSource ();
ct2.CancelAfter (timeoutInSeconds * 1000);
ct2.Token.Register (() => m_source.TrySetCancelled());

// Method #3 to set up the timeout:
System.Threading.Tasks.Task.Factory.StartNew (async () =>
{
await System.Threading.Tasks.Task.Delay (timeoutInSeconds * 1000);
m_source.TrySetCancelled();
});

// Method #4 to set up the timeout:
Xamarin.Forms.Device.StartTimer (new TimeSpan (0, 0, timeoutInSeconds),
() => m_source.TrySetCancelled());

return m_source.Task;
}

protected void Callback(string data);
{
// Got the data!
m_source.TrySetResult(data);
}
}

4 种不同的超时设置方式各有什么优缺点?例如,我猜测方法 #2 是最“轻量级”的(需要最少的系统资源)?

还有其他我错过的超时设置方法吗?

附:

我通过艰难的方式发现的一条知识 - 如果您从主 UI 线程之外的线程调用 GetDataFromServer():

Task.Run(() => await GetDataFromServer());    

在 iOS 上,第四种方法 (Xamarin.Forms.Device.StartTimer) 永远不会触发

最佳答案

我认为使用 Task.Delay 更容易和 Task.WhenAny :

public async Task<string> GetDataFromServerAsync(int timeoutInSeconds)
{
Task<string> requestTask = GetDataFromServerAsync();
var timeoutTask = Task.Delay(timeoutInSeconds);
var completedTask = await Task.WhenAny(requestTask, timeoutTask);
if (completedTask == timeoutTask)
throw new OperationCanceledException();
return await requestTask;
}

其他方法的缺点:

方法#1:创建一个新的 CancellationToken没原因。它只是方法 #2 的低效版本。

方法#2:通常,您应该处理 Register 的结果一旦任务完成。在这种情况下,它可能会正常工作,因为 CTS 最终总是会被取消。

方法#3:使用StartNew只需调用Delay - 不确定那里的推理。它本质上是 Delay 的低效版本与 WhenAny .

方法#4:可以接受。虽然你必须处理 TaskCompletionSource<T>及其怪癖(例如,默认情况下的同步延续)。

关于C# Xamarin Forms - 执行任务,超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42792618/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com