c# – Mono for Android / MonoTouch System.Net.WebException:请求已中止
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – Mono for Android / MonoTouch System.Net.WebException:请求已中止,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5619字,纯文字阅读大概需要9分钟。
内容图文
![c# – Mono for Android / MonoTouch System.Net.WebException:请求已中止](/upload/InfoBanner/zyjiaocheng/793/0ce32ac4137b41fcb06d65f3ea0e60b0.jpg)
当我使用以下代码来请求FTP服务器时.
如果请求失败,我会收到错误.我不知道为什么.
码:
try
{
FtpWebRequest request = GetFtpWebResquest(WebRequestMethods.Ftp.ListDirectoryDetails, shareInfo.Uri);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
root = new FtpResource(this, response);
}
catch (Exception e)
{
}
例外:
Unhandled Exception:
System.Net.WebException: Request aborted
at System.Net.FtpWebRequest.CheckIfAborted () [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.set_State (RequestState value) [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.ProcessRequest () [0x00000] in <filename unknown>:0
at System.Threading.Thread.StartInternal () [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.WebException: Request aborted
at System.Net.FtpWebRequest.CheckIfAborted () [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.set_State (RequestState value) [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.ProcessRequest () [0x00000] in <filename unknown>:0
at System.Threading.Thread.StartInternal () [0x00000] in <filename unknown>:0
@@@ ABORTING: INVALID HEAP ADDRESS IN dlfree addr=0x420e3580
_wapi_handle_ref: Attempting to ref unused handle 0x41c
* Assertion at /Users/builder/data/lanes/monodroid-lion-bs1/03814ac5/source/mono/mono/io-layer/wthreads.c:1365, condition `ok' not met
编辑:
为了更好地理解,我实现了一个从AsyncTask调用的简单测试方法. AsnycTask启动一次,除了GUI线程和AsyncTask之外我不使用其他线程.
在几秒钟的间隔内,AsyncTask接收我的ListView的所有条目并设置状态(离线/在线). 2到3分钟后,我得到了上面未处理的异常.
AsynTask:
#region implemented abstract members of AsyncTask
protected override Java.Lang.Object DoInBackground (params Java.Lang.Object[] @params)
{
try
{
_isRunning = true;
while (_isRunning)
{
if (Statics.IsInternetAvailable(_context))
{
AvailableShareAdapter adapter = _context.GetAvailableSharesAdapter();
if (adapter != null)
{
List<ShareInformation> list = adapter.GetAllItems();
foreach(ShareInformation si in list)
{
if (!_isRunning)
break;
si.State = ShareInformation.ShareState.Testing;
_handler.Post(new Java.Lang.Runnable(() => { _context.GetAvailableSharesAdapter().NotifyDataSetChanged(); } ));
if (_coreFacade.SimpleTest(si.Uri, si.UserName, si.Password))
si.State = ShareInformation.ShareState.Online;
else
si.State = ShareInformation.ShareState.Offline;
_handler.Post(new Java.Lang.Runnable(() => { _context.GetAvailableSharesAdapter().NotifyDataSetChanged(); } ));
}
}
Thread.Sleep(60000);
}
}
} catch(Exception e)
{
_coreFacade.Log("DoInBackground", e.ToString());
}
return null;
}
#endregion
SimpleTest:
public bool SimpleTest(string uri, string username, string password)
{
Console.WriteLine("SimpleTest called");
try {
WebRequest request = HttpWebRequest.Create(uri);
request.Credentials = new NetworkCredential(username, password);
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Timeout = 30 * 1000;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
return true;
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
return false;
}
}
编辑2:
顺便说一下……当连接失败时,我只得到这个未处理的异常.如果可用的FTP源一切正常.
解决方法:
简短的回答:这是一个Mono bug(实际上是FtpWebRequest中的一个).
切换到备用FTP客户端类/ libary(例如J.P. Trosclair的
System.Net.FtpClient),如果可能的话.
答案很长:
抛出“请求中止”异常的线程是运行时创建的线程,这就是您无法捕获异常(以及运行时终止的原因)的原因.
我最近遇到了同样的问题,花了很多时间调试它.
如果你看一下Mono的FtpWebRequest(截至目前的最新资料):
你会看到ProcessRequest(来自你的堆栈跟踪)是一个ThreadStart委托,并且感兴趣的线程确实由运行时创建(第391和442行).
事实证明,FtpWebReuqest.GetResponse()虽然是每个规范的同步,但实际上是异步的[sic!] – 第422行.这创建了动态环境(我们很快就会看到)容易出错.
以下是其中一个失败方案(TCP connect()超时)中发生的情况:
[calling thread] Create(); // FtpWebRequest object, State == RequestState.Before
[calling thread] GetResponse();
[calling thread] BeginGetResponse();
[calling thread] State = RequestState.Scheduled;
[calling thread] new Thread(ProcessRequest()).Start() // runtime-created thread
[calling thread] EndGetResponse();
[calling thread] WaitUntilComplete();
[runtime thread] ProcessRequest();
[runtime thread] ProcessMethod();
[runtime thread] State = RequestState.Connecting;
[runtime thread] OpenControlConnection();
[runtime thread] Socket.Connect();
<time passes>
[calling thread] Abort(); // WaitUntilComplete() times out
[calling thread] State = RequestState.Aborted; // [!!]
[calling thread] throw WebException("Transfer timed out");
// calling thread seems to think everything's fine, but...
<some time later>
[runtime thread] throw SocketException // Socket.Connect() times out
[runtime thread] sock = null; // from exception handler
[runtime thread] throw WebException("unable to connect to remote server");
// because sock was set to null
[runtime thread] State = RequestState.Error;
// exception is caught in ProcessRequest, an attempt is made to
// change the State to RequestState.Error, but it's already been
// set to RequestState.Aborted by the calling thread [!!]
[runtime thread] throw WebException("Request aborted");
// and this exception isn't caught anywhere... *KABOOM*
Aaaand就是这样的.不幸的是,修复属于Mono.
你肯定可以尝试通过设置超过底层套接字的connect()超时的超时来解决它,但事实是,很少有其他代码路径,其中Mono可以抛出无法处理的异常……
内容总结
以上是互联网集市为您收集整理的c# – Mono for Android / MonoTouch System.Net.WebException:请求已中止全部内容,希望文章能够帮你解决c# – Mono for Android / MonoTouch System.Net.WebException:请求已中止所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。