本文介绍了启动一个任务的背景下,如果出现某些错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的使用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:

的。

这篇关于启动一个任务的背景下,如果出现某些错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 09:36