首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ObjectDisposedException: CancellationTokenSource已被释放

ObjectDisposedException: CancellationTokenSource已被释放
EN

Stack Overflow用户
提问于 2016-06-24 17:46:05
回答 3查看 12.8K关注 0票数 9

我开始在我的MacBook专业版上使用Xamarin Studio进行Xamarin.Forms开发。我构建了一个应用程序,其目的是查询PrestaShop网站,检索产品并展示它们。

在将应用程序部署到Android时,我在低于棉花糖的版本中遇到了一些问题,但我解决了它们,所以我不在这里描述它们。

在将应用程序部署到iOS (模拟器)时,我仍然有一个严重的问题。应用程序运行了,但是当我单击按钮检索数据时,它崩溃了,给出了一个System.ObjectDisposedException,它的消息是"The CancellationTokenSource has me disposed“。我会在这里粘贴相关的源代码:

代码语言:javascript
运行
复制
async void button1_Click(object sender, System.EventArgs e)
{
    try
    {
        HttpClientHandler hnd = new HttpClientHandler();
        hnd.Credentials = new NetworkCredential("[apikey]", "");
        string res;
        using (var client = new HttpClient(hnd))
        {
            var responseText = await client.GetStringAsync("[endpoint]/products");
            using (MemoryStream stream = new MemoryStream())
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write(responseText.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", string.Empty));
                writer.Flush();
                stream.Position = 0;
                XDocument doc = XDocument.Load(stream);
                res = JsonConvert.SerializeXNode(doc, Formatting.Indented, true);
            }
            var data = JsonConvert.DeserializeObject<Dictionary<string, object>>(res);
            //Result.Text = data["products"].GetType().ToString() + Result.Text;
            Func<string, Task> creator_method = async (string id) =>
            {
                try
                {
                    var responseProd = await client.GetStringAsync($"[endpoint]/products/{id}"); // AT THIS ROW THE EXCEPTION IS RAISED!!!
                    using (MemoryStream stream = new MemoryStream())
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write(responseProd.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", string.Empty));
                        writer.Flush();
                        stream.Position = 0;
                        XDocument doc = XDocument.Load(stream);
                        res = JsonConvert.SerializeXNode(doc, Formatting.Indented, true);
                    }
                    var product_rawData = JsonConvert.DeserializeObject<Dictionary<string, object>>(res);
                    var productData = (JObject)product_rawData["product"];
                    try
                    {
                        views.Children.Add(new ProductXaml(productData["name"]["language"]["#cdata-section"].ToString(), float.Parse(productData["price"]["#cdata-section"].ToString().Replace('.', ',')), productData["id_default_image"]["@xlink:href"].ToString()));
                    }
                    catch (NullReferenceException nre)
                    {
                        views.Children.Add(new ProductXaml(productData["name"]["language"]["#cdata-section"].ToString(), float.Parse(productData["price"]["#cdata-section"].ToString().Replace('.', ',')), ""));
                    }
                }
                catch (Exception gex) { throw; }
            };
            foreach (var product in ((JObject)data["products"])["product"])
                try
                {
                    Device.BeginInvokeOnMainThread(async () => { await creator_method.Invoke(product["@id"].ToString()); });
                }
                catch (TaskCanceledException tce) { continue; }
                catch (WebException we) { continue;}
        }
    }
    catch (HttpRequestException ex)
    {
        Result.Text = ex.Message;
    }
}

我该如何解决这个问题呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-25 00:16:20

“CancellationTokenSource已被释放”

您的using (var client = new HttpClient())...CancellationToken似乎已被第一个client.GetStringAsync()调用占用。

如何修复此

我建议将第二个调用放在它自己的using块中,以避免这种情况。

下面是您的代码现在应该是什么样子,以及第二个using语句:

代码语言:javascript
运行
复制
async void button1_Click(object sender, System.EventArgs e)
{
    try
    {
        HttpClientHandler hnd = new HttpClientHandler();
        hnd.Credentials = new NetworkCredential("[apikey]", "");
        string res;
        using (var client = new HttpClient(hnd))
        {
            var responseText = await client.GetStringAsync("[endpoint]/products");
            using (MemoryStream stream = new MemoryStream())
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write(responseText.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", string.Empty));
                writer.Flush();
                stream.Position = 0;
                XDocument doc = XDocument.Load(stream);
                res = JsonConvert.SerializeXNode(doc, Formatting.Indented, true);
            }
            var data = JsonConvert.DeserializeObject<Dictionary<string, object>>(res);
            //Result.Text = data["products"].GetType().ToString() + Result.Text;
            Func<string, Task> creator_method = async (string id) =>
            {
                try
                {
                    using (var newClient = new HttpClient(hnd)) // Create a new client to avoid your other one's token being consumed
                    {
                        var responseProd = await newClient.GetStringAsync($"[endpoint]/products/{id}");
                        using (MemoryStream stream = new MemoryStream())
                        using (StreamWriter writer = new StreamWriter(stream))
                        {
                            writer.Write(responseProd.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", string.Empty));
                            writer.Flush();
                            stream.Position = 0;
                            XDocument doc = XDocument.Load(stream);
                            res = JsonConvert.SerializeXNode(doc, Formatting.Indented, true);
                        }
                        var product_rawData = JsonConvert.DeserializeObject<Dictionary<string, object>>(res);
                        var productData = (JObject)product_rawData["product"];
                        try
                        {
                            views.Children.Add(new ProductXaml(productData["name"]["language"]["#cdata-section"].ToString(), float.Parse(productData["price"]["#cdata-section"].ToString().Replace('.', ',')), productData["id_default_image"]["@xlink:href"].ToString()));
                        }
                        catch (NullReferenceException nre)
                        {
                            views.Children.Add(new ProductXaml(productData["name"]["language"]["#cdata-section"].ToString(), float.Parse(productData["price"]["#cdata-section"].ToString().Replace('.', ',')), ""));
                        }
                    }
                }
                catch (Exception gex) { throw; }
            };
            foreach (var product in ((JObject)data["products"])["product"])
                try
                {
                    Device.BeginInvokeOnMainThread(async () => { await creator_method.Invoke(product["@id"].ToString()); });
                }
                catch (TaskCanceledException tce) { continue; }
                catch (WebException we) { continue;}
        }
    }
    catch (HttpRequestException ex)
    {
        Result.Text = ex.Message;
    }
}

希望这能有所帮助!:)

票数 9
EN

Stack Overflow用户

发布于 2018-02-28 14:45:54

我也遇到了同样的问题,我对所有的api请求都使用了一个httpclient。

代码语言:javascript
运行
复制
private static HttpClient httpClient;

public static HttpClient GetHttpClient()
{
    if (httpClient == null)
    {
        httpClient = new HttpClient()
        {
            BaseAddress = new Uri(BaseUrl)
        };
        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    }

    return httpClient;
}

似乎您使用的(var client =HttpClient())...的CancellationToken已被第一个client.GetStringAsync()调用消耗。

Geoff的回答是:我删除了我的静态httpclient,现在为所有请求创建了一个新的httpclient,it's fixed my issue。

代码语言:javascript
运行
复制
public static HttpClient GetHttpClient()
{
    HttpClient httpClient = new HttpClient()
    {
        BaseAddress = new Uri(BaseUrl)
    };
    httpClient.DefaultRequestHeaders.Accept.Clear();
    httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

    return httpClient;
}
票数 0
EN

Stack Overflow用户

发布于 2019-03-05 04:38:18

创建HttpClient的新实例,如下所示

代码语言:javascript
运行
复制
public static HttpClient GetHttpClient()
{
    HttpClient httpClient = new HttpClient()
    {
        BaseAddress = new Uri(BaseUrl)
    };
    httpClient.DefaultRequestHeaders.Accept.Clear();
    httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

return httpClient;

}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38010374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档