我正在尝试解决我的某个智能设备项目(Windows Mobile 6.5设备上的.NET CF 3.5)的问题。
代码尝试连续进行webservice调用以获取一些数据并在表单中使用它。在使用过程中,对于特定情况,抛出了ObjectDisposedException,应用程序崩溃。堆栈跟踪是
System.ObjectDisposedException was unhandled
Message="ObjectDisposedException"
ObjectName=""
StackTrace:
at System.Threading.Timer.throwIfDisposed()
at System.Threading.Timer.Change(UInt32 dueTime, UInt32 period)
at System.Threading.Timer.Change(Int32 dueTime, Int32 period)
at System.Net.HttpWebRequest.startReadWriteTimer()
at System.Net.HttpWebRequest.ConnectionClient.Read(Byte[] data, Int32 offset, Int32 length)
at System.Net.HttpReadStream.NetworkRead(Byte[] data, Int32 offset, Int32 length)
at System.Net.ChunkedReadStream.fillBuffer()
at System.Net.ChunkedReadStream.getLine()
at System.Net.ChunkedReadStream.doRead(Byte[] data, Int32 offset, Int32 length)
at System.Net.HttpReadStream.ReadToDrain(Byte[] buffer, Int32 offset, Int32 length)
at System.Net.HttpReadStream.doClose()
at System.Net.HttpReadStream.Finalize()
我已经阅读了很多博客和论坛,包括这个,建议的解决方案似乎是在收到回复之前关闭请求流和请求。
requestStream = webRequest.GetRequestStream();
requestStream.Close(); // WE NEED THIS LINE in order to avoid the ObjectDisposedException.
但这对我的情况没有帮助。如果在将数据写入流之前关闭requestStream,则它不会执行任何操作。如果我在获得响应后关闭,则会抛出InvalidOperationException。
以下是我的代码:
Reference.cs
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="ProductResolveServiceSOAP11Binding", Namespace="urn:ProductResolveService")]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Exception))]
public partial class ProductResolveService : System.Web.Services.Protocols.SoapHttpClientProtocol {
/// <remarks/>
public ProductResolveService() {
this.Url = "http://172.26.37.115:8080/axis/services/ProductResolveService";
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:getResolvedEpcs", RequestNamespace="http://services.axis.oatsystems.com", ResponseNamespace="http://services.axis.oatsystems.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("return", IsNullable=true)]
public ResolvedProductList getResolvedEpcs([System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] EpcToResolve message) {
object[] results = this.Invoke("getResolvedEpcs", new object[] {
message});
return ((ResolvedProductList)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BegingetResolvedEpcs(EpcToResolve message, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("getResolvedEpcs", new object[] {
message}, callback, asyncState);
}
/// <remarks/>
public ResolvedProductList EndgetResolvedEpcs(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((ResolvedProductList)(results[0]));
}
}
Form1.cs的
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Web.Services.Protocols;
using System.Windows.Forms;
using NFEHandlingProject.StatusService;
using System.IO;
using MVProductResolveService;
namespace NFEHandlingProject
{
public partial class Form1 : Form
{
private Thread resolveThread;
int counter = 0;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
if (resolveThread == null)
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: Creating Thread"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
resolveThread = new Thread(new ThreadStart(GetEpcProductMapping));
resolveThread.IsBackground = true;
resolveThread.Priority = ThreadPriority.BelowNormal;
resolveThread.Start();
}
}
object syncRoot2 = new object();
bool resolving = false;
private void GetEpcProductMapping()
{
lock (syncRoot2)
{
if (resolving)
{
return;
}
resolving = true;
}
while (resolving)
{
using (ProductResolveService2 productResolveService = new ProductResolveService2())
{
EpcToResolve epcToResolve = null;
try
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: Resolving..."); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
productResolveService.Url = "http://172.26.37.115:8080/axis/services/ProductResolveService?wsdl";
productResolveService.Timeout = 60000;
// The input object that is sent to xpress
epcToResolve = new EpcToResolve();
string epcBase = "3410402AEA0000000000";
int baseDec = Convert.ToInt32("1000", 16);
// Creating the input of epc's baed on the ResolveBatchSize and number epcs's that needs to be resolved at xpress
string[] epcs = new string[1];
for (int i = 0; i < 1; i++)
{
int epcDec = baseDec + i;
epcs[i] = epcBase + epcDec.ToString("X");
}
// setting the epc list which is the input that is sent to xpress
epcToResolve.epcList = epcs;
//pass the flag to check if say whether the productInformation or just the product_id is resolved
epcToResolve.returnOnlyProductId = false;
//return productResolveService.getResolvedEpcs(epcToResolve);
productResolveService.getResolvedEpcs(epcToResolve);
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolved"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
catch (SoapHeaderException)
{
// do nothing
}
catch (SoapException se)
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Problem resolving products at xpress"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
catch (WebException we)
{
// get the reason for the exception
WebExceptionStatus status = we.Status;
String description = we.Message;
WebResponse response = we.Response;
if (response != null)
{
Stream respStream = response.GetResponseStream();
if (respStream != null)
{
respStream.Close();
respStream.Dispose();
respStream = null;
}
// close the response
response.Close();
response = null;
}
// Case when there is no connectivity. Just display an error message to the user to indicate that there is no connectivity.
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: There is no connectivity to xpress"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
catch (ThreadAbortException)
{
// Do nothing. Do not log
}
catch (System.Exception e)
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("An exception occured when fetching data from xpress"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
try
{
Thread.Sleep(200);
}
catch
{
}
}
}
resolving = false;
}
private void btnStop_Click(object sender, EventArgs e)
{
if (resolveThread != null && resolving)
{
resolveThread.Abort();
resolveThread.Join();
resolveThread = null;
resolving = false;
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: Stopped Thread"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
}
}
}
单击表单中的“开始”按钮,创建线程并继续调用Web服务,当调用stop时,线程将停止。重复启动和停止会导致ObjectDisposedException(这就是我重现此异常的方式)。
对此方面的任何帮助都将受到高度赞赏,因为我一直试图解决这个问题几天。
由于 塞特希
答案 0 :(得分:1)
这是一篇非常古老的帖子。但是,我想在这里为任何仍在寻找答案的机构记录我的答案。
两个选项:
使用以下解决方案。
public class ExtendedDataImport : DataImport.DataImport
{
private WebRequest webRequest;
private WebResponse webResponse;
/// <summary>
/// This method overrides the generated method and sets parameters so that HTTP 1.0
/// is used (without chunking). If left with default parameters it
/// sometimes fails.
/// </summary>
protected override WebRequest GetWebRequest(Uri uri)
{
webRequest = base.GetWebRequest(uri);
((HttpWebRequest)webRequest).KeepAlive = false;
((HttpWebRequest)webRequest).ProtocolVersion = HttpVersion.Version10;
return webRequest;
}
protected override WebResponse GetWebResponse(WebRequest request)
{
webResponse = base.GetWebResponse(request);
return webResponse;
}
public void Close()
{
if (webResponse != null)
{
Stream responseStream = webResponse.GetResponseStream();
responseStream.Close();
responseStream.Dispose();
responseStream = null;
webResponse.Close();
webResponse = null;
}
if (webRequest != null)
{
// Aborting the WebRequest, cleans up the webrequest and
// stops the timer which causes the ObjectDisposedException
try
{
webRequest.Abort();
webRequest = null;
}
catch (ObjectDisposedException ex)
{
// Ignoring the object disposed exception as mentioned in the follwoing link
//http://social.msdn.microsoft.com/Forums/en/netfxcompact/thread/8f21514c-9b7c-40d3-96c9-794c0dc167fe
}
}
}
protected override void Dispose(bool disposing)
{
Close();
base.Dispose(disposing);
}
}