问题描述
我使用的使用Mono.Mac(3.2.3)与服务器通信的一些休息的请求,并作为重试机制,我悄悄地试图给HTTP动作多次尝试,如果他们失败了,或超时。
I am using some REST requests using Mono.Mac (3.2.3) to communicate with a server, and as a retry mechanism I am quietly attempting to give the HTTP actions multiple tries if they fail, or time out.
我有以下;
var tries = 0;
while (tries <= ALLOWED_TRIES)
{
try
{
postTask.Start();
tries++;
if (!postTask.Wait(Timeout))
{
throw new TimeoutException("Operation timed out");
}
break;
} catch (Exception e) {
if (tries > ALLOWED_TRIES)
{
throw new Exception("Failed to access Resource.", e);
}
}
}
当任务使用的参数像这样的父类的方法;
Where the task uses parameters of the parent method like so;
var postTask = new Task<HttpWebResponse>(() => {return someStuff(foo, bar);},
Task.Factory.CancellationToken,
Task.Factory.CreationOptions);
这个问题似乎是,任务不希望与 postTask.Start()后,它的第一个竣工(以及随后的故障)。是否有这样做的一个简单的方法,还是我用这种方式滥用的任务?是否有某种方式,该任务重置为初始状态,还是我最好使用一个工厂某种?
The problem seems to be that the task does not want to be run again with postTask.Start()
after it's first completion (and subsequent failure). Is there a simple way of doing this, or am I misusing tasks in this way? Is there some sort of method that resets the task to its initial state, or am I better off using a factory of some sort?
推荐答案
您要真是滥用工作
在这里,有几个原因:
You're indeed misusing the Task
here, for a few reasons:
-
您不能运行相同的任务不止一次。当它这样做,它的完成。
You cannot run the same task more than once. When it's done, it's done.
这是不建议手动构建一个工作
对象,有 Task.Run
和 Task.Factory.Start
为
It is not recommended to construct a Task
object manually, there's Task.Run
and Task.Factory.Start
for that.
您不应该使用 Task.Run
/ Task.Factory.Start
为其做任务IO绑定工作。它们主要用于CPU密集型的工作,因为他们借从线程池
一个线程来执行任务操作。相反,用纯异步工作
此为基础的API,它不需要奉献线程来完成。
You should not use Task.Run
/Task.Factory.Start
for a task which does IO-bound work. They are intended for CPU-bound work, as they "borrow" a thread from ThreadPool
to execute the task action. Instead, use pure async Task
-based APIs for this, which do not need a dedicate thread to complete.
例如,下面你可以从UI线程调用 GetResponseWithRetryAsync
,仍然保持UI响应:
For example, below you can call GetResponseWithRetryAsync
from the UI thread and still keep the UI responsive:
async Task<HttpWebResponse> GetResponseWithRetryAsync(string url, int retries)
{
if (retries < 0)
throw new ArgumentOutOfRangeException();
var request = WebRequest.Create(url);
while (true)
{
try
{
var result = await request.GetResponseAsync();
return (HttpWebResponse)result;
}
catch (Exception ex)
{
if (--retries == 0)
throw; // rethrow last error
// otherwise, log the error and retry
Debug.Print("Retrying after error: " + ex.Message);
}
}
}
更多阅读:
More reading:
的。
这篇关于启动一个任务的背景下,如果出现某些错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!