Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-并发I/O操作异常_C#_Windows Phone 7_Viewmodel_Webclient - Fatal编程技术网

C#-并发I/O操作异常

C#-并发I/O操作异常,c#,windows-phone-7,viewmodel,webclient,C#,Windows Phone 7,Viewmodel,Webclient,我有一个刷新按钮来更新WP7应用程序中的新闻。当我双击或三次点击刷新按钮时,我得到了一个错误 "WebClient does not support concurrent I/O operations" . 我认为这是因为它将请求发送了三次,导致请求崩溃。这是我的点击代码 private void NewsRefresh_Click(object sender, RoutedEventArgs e) { var vm = this.DataContext as

我有一个刷新按钮来更新WP7应用程序中的新闻。当我双击或三次点击刷新按钮时,我得到了一个错误

"WebClient does not support concurrent I/O operations" .
我认为这是因为它将请求发送了三次,导致请求崩溃。这是我的点击代码

    private void NewsRefresh_Click(object sender, RoutedEventArgs e)
    {
        var vm = this.DataContext as MainPageViewModel;
        if (vm != null)
        {
            vm.UpdateNews();
        }
    }
如何将其设置为“如果它正忙,请取消流程”。

简单的方法(尽管不是防弹的):

更困难的方法需要更多关于MainPageViewModel到底是什么以及UpdateNews()做什么的细节。基本上,您需要在存储WebClient实例的任何位置存储状态值。在使用WebClient之前,您需要检查是否已经在使用它。当多个线程可能对单个实例进行操作时,或者如果您需要执行多个操作(UpdateNews除外),就会出现问题。当涉及多个线程时,最简单的方法是使用一个线程来包围WebClient

当然,另一个选择是不要重用WebClient实例,而是为每个新请求创建一个新实例

更新


好吧,好吧,使用DownloadStringAsync肯定会让事情变得有趣。除非移动重新启用的代码,否则上述禁用UI的代码将无法工作。按照我的上一个建议,创建一个新的WebClient实例是最简单的。我自己不太喜欢WebClient,更喜欢使用它。

WebClient不是很灵活,但如果您真的想使用它,可以使用IsBusy属性,然后取消正在进行的操作。然后,一旦取消,您可以重新启动它。同步有一个重要的问题。由检查IsBusy和调用CancelAsync组成的操作不是原子操作。幸运的是,DownloadStringCompleted被分派到UI线程,因此您不需要为同步而烦恼。下面的代码片段展示了如何实现它。为简单起见,它是Windows窗体

public partial class Form1 : Form
{
    WebClient _WebClient;
    bool _UpdateNews;

    public Form1()
    {
        InitializeComponent();
        _WebClient = new WebClient();
        _WebClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(_WebClient_DownloadStringCompleted);
        _UpdateNews = false;
    }

    void _WebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (_UpdateNews)
        {
            _UpdateNews = false;
            UpdateNews();
        }
        else if (e.Error != null)
        {
            // Report error 
        }
        else
        {
            MessageBox.Show(e.Result);
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (_WebClient.IsBusy)
        {
            _WebClient.CancelAsync();
            _UpdateNews = true;
        }
        else
        {
            UpdateNews();
        }
    }

    private void UpdateNews()
    {
        _WebClient.DownloadStringAsync(new Uri("http://stackoverflow.com/questions/7084948/c-concurrent-i-o-operations-exception"));
    }
}

介绍二等兵bool IspendingRefresh我会查一查。顺便说一句,UpdateNews()正在下载feed newsWebClient.DownloadStringAsync(新Uri(“);如果刷新是取消当前操作的唯一原因,您可能希望删除_UpdateNews字段并使用e.Cancelled。我没有将其包含在剪报中以使其更通用。
public partial class Form1 : Form
{
    WebClient _WebClient;
    bool _UpdateNews;

    public Form1()
    {
        InitializeComponent();
        _WebClient = new WebClient();
        _WebClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(_WebClient_DownloadStringCompleted);
        _UpdateNews = false;
    }

    void _WebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (_UpdateNews)
        {
            _UpdateNews = false;
            UpdateNews();
        }
        else if (e.Error != null)
        {
            // Report error 
        }
        else
        {
            MessageBox.Show(e.Result);
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (_WebClient.IsBusy)
        {
            _WebClient.CancelAsync();
            _UpdateNews = true;
        }
        else
        {
            UpdateNews();
        }
    }

    private void UpdateNews()
    {
        _WebClient.DownloadStringAsync(new Uri("http://stackoverflow.com/questions/7084948/c-concurrent-i-o-operations-exception"));
    }
}