我的目的是写一个下载网页的类,类写好以后在运行的时候出错。
调用public void DoDownload(string BaseUrl, string RelativeUrl)这个函数的时候,直接跳到程序的入口点Application.Run(new Form1())报出错了。
未处理TargetInvocationException
调用的目标发生了异常。
InnerException的Message是:未将对象引用设置到对象的实例。
完整的错误信息附在后面。
namespace Download
{
public enum DownloadStatus
{
Success, Failed, Canceled
} public struct DownloadArgs
{
public Int32 Identifier;
public string SourceUrl;
public string Result;
public DownloadStatus Status;
public Exception Error;
} public delegate void DownLoadCompleteHandle(object sender, DownloadArgs e);
public delegate void DownloadProgressChangedHandle(object sender, System.Net.DownloadProgressChangedEventArgs e); public class Download
{
public event DownLoadCompleteHandle DownloadComplete;
public event DownloadProgressChangedHandle DownloadProgressChanged; Int32 iIdentifier;
System.Net.WebClient wcDownload;
string sSourceUrl; public Download(Int32 Identifier)
{
iIdentifier = Identifier;
wcDownload = new System.Net.WebClient();
wcDownload.Encoding = System.Text.Encoding.UTF8;
wcDownload.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(wcDownload_DownloadProgressChanged);
wcDownload.DownloadStringCompleted += new System.Net.DownloadStringCompletedEventHandler(wcDownload_DownloadStringCompleted);
} void wcDownload_DownloadStringCompleted(object sender, System.Net.DownloadStringCompletedEventArgs e)
{
DownloadArgs daT = new DownloadArgs();
daT.SourceUrl = sSourceUrl;
if (e.Error != null)
{
daT.Status = DownloadStatus.Failed;
daT.Error = e.Error;
}
else
{
if (e.Cancelled)
{
daT.Status = DownloadStatus.Canceled;
}
else
{
daT.Identifier = iIdentifier;
daT.Result = System.Text.Encoding.Default.GetString(System.Text.Encoding.UTF8.GetBytes(e.Result));
daT.Status = DownloadStatus.Success;
}
}
DownloadComplete(sender, daT);
} void wcDownload_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
{
DownloadProgressChanged(sender, e);
} public void DoDownload(string BaseUrl, string RelativeUrl)
{
System.Uri uri;
if (BaseUrl.Length > 0)
{
if (System.Uri.TryCreate(new Uri(BaseUrl), RelativeUrl, out uri))
{
sSourceUrl = uri.AbsoluteUri;
}
}
else
{
sSourceUrl = RelativeUrl;
}
wcDownload.DownloadStringAsync(new Uri(sSourceUrl));
} public bool IsBusy
{
get
{
return wcDownload.IsBusy;
}
}
}
}完整错误信息:
未处理 System.Reflection.TargetInvocationException
Message="调用的目标发生了异常。"
Source="mscorlib"
StackTrace:
在 System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
在 System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
在 System.Delegate.DynamicInvokeImpl(Object[] args)
在 System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
在 System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
在 System.Threading.ExecutionContext.runTryCode(Object userData)
在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
在 System.Windows.Forms.Control.InvokeMarshaledCallbacks()
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.Run(Form mainForm)
在 Test.Program.Main() 位置 E:\Visual Studio 2005\Test\Test\Program.cs:行号 17
在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
调用public void DoDownload(string BaseUrl, string RelativeUrl)这个函数的时候,直接跳到程序的入口点Application.Run(new Form1())报出错了。
未处理TargetInvocationException
调用的目标发生了异常。
InnerException的Message是:未将对象引用设置到对象的实例。
完整的错误信息附在后面。
namespace Download
{
public enum DownloadStatus
{
Success, Failed, Canceled
} public struct DownloadArgs
{
public Int32 Identifier;
public string SourceUrl;
public string Result;
public DownloadStatus Status;
public Exception Error;
} public delegate void DownLoadCompleteHandle(object sender, DownloadArgs e);
public delegate void DownloadProgressChangedHandle(object sender, System.Net.DownloadProgressChangedEventArgs e); public class Download
{
public event DownLoadCompleteHandle DownloadComplete;
public event DownloadProgressChangedHandle DownloadProgressChanged; Int32 iIdentifier;
System.Net.WebClient wcDownload;
string sSourceUrl; public Download(Int32 Identifier)
{
iIdentifier = Identifier;
wcDownload = new System.Net.WebClient();
wcDownload.Encoding = System.Text.Encoding.UTF8;
wcDownload.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(wcDownload_DownloadProgressChanged);
wcDownload.DownloadStringCompleted += new System.Net.DownloadStringCompletedEventHandler(wcDownload_DownloadStringCompleted);
} void wcDownload_DownloadStringCompleted(object sender, System.Net.DownloadStringCompletedEventArgs e)
{
DownloadArgs daT = new DownloadArgs();
daT.SourceUrl = sSourceUrl;
if (e.Error != null)
{
daT.Status = DownloadStatus.Failed;
daT.Error = e.Error;
}
else
{
if (e.Cancelled)
{
daT.Status = DownloadStatus.Canceled;
}
else
{
daT.Identifier = iIdentifier;
daT.Result = System.Text.Encoding.Default.GetString(System.Text.Encoding.UTF8.GetBytes(e.Result));
daT.Status = DownloadStatus.Success;
}
}
DownloadComplete(sender, daT);
} void wcDownload_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
{
DownloadProgressChanged(sender, e);
} public void DoDownload(string BaseUrl, string RelativeUrl)
{
System.Uri uri;
if (BaseUrl.Length > 0)
{
if (System.Uri.TryCreate(new Uri(BaseUrl), RelativeUrl, out uri))
{
sSourceUrl = uri.AbsoluteUri;
}
}
else
{
sSourceUrl = RelativeUrl;
}
wcDownload.DownloadStringAsync(new Uri(sSourceUrl));
} public bool IsBusy
{
get
{
return wcDownload.IsBusy;
}
}
}
}完整错误信息:
未处理 System.Reflection.TargetInvocationException
Message="调用的目标发生了异常。"
Source="mscorlib"
StackTrace:
在 System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
在 System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
在 System.Delegate.DynamicInvokeImpl(Object[] args)
在 System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
在 System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
在 System.Threading.ExecutionContext.runTryCode(Object userData)
在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
在 System.Windows.Forms.Control.InvokeMarshaledCallbacks()
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.Run(Form mainForm)
在 Test.Program.Main() 位置 E:\Visual Studio 2005\Test\Test\Program.cs:行号 17
在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
wcDownload.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(wcDownload_DownloadProgressChanged);
这行删掉就不会报错了。就是说,我不能定阅DownloadProgressChanged 这个事件。Why?
{
iIdentifier = Identifier;
wcDownload = new System.Net.WebClient();
wcDownload.Encoding = System.Text.Encoding.UTF8;
wcDownload.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(wcDownload_DownloadProgressChanged);
wcDownload.DownloadStringCompleted += new System.Net.DownloadStringCompletedEventHandler(wcDownload_DownloadStringCompleted);
} 这里最后要加wcDowload.DownloadData或DownloadString(url)吧
void wcDownload_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
{
// DownloadProgressChanged(sender, e); <-- 空
// 改为
if (DownloadProgressChanged != null)
DownloadProgressChanged(sender, e);
} 2 你处理了Download.DownloadProgressChanged事件,并在这个事件中处理UI更新。这时会出现多线程更新UI的问题。
第2点就没什么问题了,一个lock就解决了。