【问题标题】:Exceptions after AsyncCallbackAsyncCallback 之后的异常
【发布时间】:2012-11-03 14:41:54
【问题描述】:

我遇到了AsyncCallback 函数的问题。我正在使用一个来下载数据,然后无论我做什么,它都会引发一个不同的异常。一些代码:

private void downloadBtn_Click(object sender, RoutedEventArgs e)
{
    string fileName = System.IO.Path.GetFileName(Globals.CURRENT_PODCAST.Title.Replace(" ", string.Empty));
    MessageBox.Show("Download is starting");
    file = IsolatedStorageFile.GetUserStoreForApplication();
    streamToWriteTo = new IsolatedStorageFileStream(fileName, FileMode.Create, file);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(Globals.CURRENT_PODCAST.Uri));
    request.AllowReadStreamBuffering = false;
    request.BeginGetResponse(new AsyncCallback(GetData), request);
}

private void GetData(IAsyncResult result)
{
    HttpWebRequest request = (HttpWebRequest)result.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
    Stream str = response.GetResponseStream();
    byte[] data = new byte[16* 1024];
    long totalValue = response.ContentLength;
    while (str.Read(data, 0, data.Length) > 0)
    {
        if (streamToWriteTo.CanWrite)
            streamToWriteTo.Write(data, 0, data.Length);
        else
            MessageBox.Show("Could not write to stream");
    }
    streamToWriteTo.Close();
    MessageBox.Show("Download Finished");
}

有什么方法可以判断异步回调何时完成,然后运行代码而不会崩溃,或者我在这里做错了什么?

【问题讨论】:

  • 你肯定做错了什么。您的读/写循环可能会写入太多数据。例如,您的循环始终写入 16 KB 的块。因此,即使您只下载 23 个字节,也会写入完整的 16 KB。此外,您永远不会关闭响应或响应流。这几乎肯定会导致问题。如果您需要更具体的建议,您需要告诉我们您遇到了哪些例外情况。
  • 我结束 get 响应,如果这就是你的意思吗?:HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
  • 查看HttpWebResponse.CloseStream.Close
  • 刚刚试了这两个,MessageBox.Show上仍然报错,除了:“System.Windows.ni.dll中发生'System.UnauthorizedAccessException'类型的异常但未处理在用户代码中”
  • 是您从线程池线程调用MessageBox.Show 的问题吗?通常,您希望在 GUI 线程上执行此操作。如果您删除对MessageBox.Show 的调用会怎样?

标签: c# .net httpwebrequest asynccallback


【解决方案1】:

问题是您正在从线程池线程调用MessageBox.Show。您需要从 UI 线程调用它。为此,您需要与 UI 线程同步。例如:

this.Invoke((MethodInvoker) delegate
    { MessageBox.Show("success!"); });

Invoke 的调用将在 UI 线程上执行代码。有关详细信息,请参阅 Control.Invoke 的文档。

【讨论】:

  • 错误背后的理论是正确的,如果我使用的是表单应用程序,这将是完美的,所以我标记了正确的答案。要修复的实际代码是(Windows Phone 7): Dispatcher.BeginInvoke(delegate { ShowCompletionMessage(); }); -- 非常感谢!
猜你喜欢
  • 1970-01-01
  • 2011-02-01
  • 2018-12-13
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多