- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我开始在 MacBook Pro 上使用 Xamarin Studio 进行 Xamarin.Forms 开发。我构建了一个应用程序,其目的是查询 PrestaShop 网站、检索产品并显示它们。
在将应用程序部署到Android时,我在Marshmallow以下的版本中遇到了一些问题,但我解决了它们,所以我不会在这里描述它们。
将应用程序部署到 iOS(模拟器)时,我仍然遇到一个严重问题。应用程序运行,但当我单击按钮检索数据时,它崩溃并给出 System.ObjectDisposeException,其消息是“CancellationTokenSource 已被处置”。我将相关的源代码粘贴在这里:
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;
}
}
我该如何解决这个问题?
最佳答案
"The CancellationTokenSource has been disposed"
看来您的 using (var client = new HttpClient())...
的 CancellationToken
已被第一个 client.GetStringAsync 消耗()
调用。
如何解决此问题
我建议将第二个调用放在自己的 using
block 中,以避免这种情况。
您的代码现在应如下所示,其中包含第二个 using
语句:
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;
}
}
希望这有帮助! :)
关于c# - 对象处置异常 : The CancellationTokenSource has been disposed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38010374/
这是我正在使用的代码。我想要的是当屏幕出现时,while循环中的代码运行。当屏幕消失时,我需要它停止。有人可以就我是否正确使用 CancellationTokenSource 来提供此功能的建议。我还
假设我创建了一个任务 bool aBoolean = true; Task.Factory.StartNew(() => while(aBooloean) { ...
有人可以举个例子,我应该使用带有三个参数的下一个方法。 var tokenSource = new CancellationTokenSource(); var token = tokenSource
我有一个这样的 Worker 类: public class Worker { private List _someObjectList = null; public Worker(S
在这种情况下,如果用户按回车键取消任务,则由 ContinueWith Hook 的其他任务将运行,但根据 AggregateException,情况并非如此 尽管 ContinueWith 中的显式
这个问题在这里已经有了答案: When to dispose CancellationTokenSource? (7 个答案) 关闭 9 年前。 我应该什么时候处理 CancellationToke
CancellationTokenSource 类是一次性的。快速查看 Reflector 证明使用了 KernelEvent,这是一种(很可能)非托管资源。由于 CancellationTokenS
我有一个这样的应用程序: 我有一个应用程序,其中一部分代码在带有计时器延迟的循环中运行。在申请开始时,我声明: public static CancellationTokenSource tokenS
正如我阅读文档 CancellationTokenSource.Cancel 不应该抛出异常。 CancellationTokenSource.Cancel 在 cts.Cancel() 调用下方;导
我开始在 MacBook Pro 上使用 Xamarin Studio 进行 Xamarin.Forms 开发。我构建了一个应用程序,其目的是查询 PrestaShop 网站、检索产品并显示它们。 在
正如我阅读文档 CancellationTokenSource.Cancel 不应该抛出异常。 CancellationTokenSource.Cancel 在 cts.Cancel() 调用下方;导
我有一个接受 CancellationToken 的方法,该方法允许该方法的用户取消其正在执行的操作。在该方法中,我使用此 CancellationToken 以及 CancellationToken
static void Main(string[] args) { CancellationTokenSource cts = new CancellationTokenSou
我正在尝试根据这篇文章实现一些重试逻辑(但有任务) Cleanest way to write retry logic? 重试逻辑的想法是在给定的时间后执行第二个任务触发取消 void Main()
我想知道使用 CancellationTokenSource 结束循环任务和退出标志之间是否有任何区别 CancellationTokenSource: CancellationTokenSource
我想知道使用 CancellationTokenSource 结束循环任务和退出标志之间是否有任何区别 CancellationTokenSource: CancellationTokenSource
我看到这段代码在我面前,我很怀疑: CancellationTokenSource _cts; public void Dispose(); { _cts.Cancel(); _cts
发布Async Targeting Pack提示我使用 ILSpy看看是什么Task-based Asynchronous Pattern (TAP)那里提供了扩展方法(其中一些我已经自己实现用于 V
这与我的另一个问题有关How to cancel background printing . 我试图更好地理解 CancellationTokenSource 模型以及如何跨线程边界使用它。 我有一个
例如,如果我想取消 Dispose() 中的某个操作调用(其中 can be called multiple times ),然后我需要写 public void Dispose() { if
我是一名优秀的程序员,十分优秀!