首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ManualResetEvent等待设置后不会释放

ManualResetEvent等待设置后不会释放
EN

Stack Overflow用户
提问于 2013-10-20 18:35:01
回答 2查看 860关注 0票数 0

我正在从webs下载两个JSON文件,之后我希望允许加载两个页面,但不允许在之前加载。但是,为了加载页面而需要设置的ManualResetEvent永远不会“触发”。即使我知道它已经设置好了,WaitOne也再也不会回来了。

方法启动下载:

代码语言:javascript
复制
private void Application_Launching(object sender, LaunchingEventArgs e)
{
    PhoneApplicationService.Current.State["doneList"] = new List<int>();
    PhoneApplicationService.Current.State["manualResetEvent"] = new ManualResetEvent(false);

    Helpers.DownloadAndStoreJsonObject<ArticleList>("http://arkad.tlth.se/api/get_posts/", "articleList");
    Helpers.DownloadAndStoreJsonObject<CompanyList>("http://arkad.tlth.se/api/get_posts/?postType=webbkatalog", "catalog");
}

下载方法,它设置ManualResetEvent

代码语言:javascript
复制
public static void DownloadAndStoreJsonObject<T>(string url, string objName)
{
    var webClient = new WebClient();
    webClient.DownloadStringCompleted += (sender, e) => 
    {
        if (!string.IsNullOrEmpty(e.Result))
        {
            var obj = ProcessJson<T>(e.Result);
            PhoneApplicationService.Current.State[objName] = obj;


            var doneList = PhoneApplicationService.Current.State["doneList"] as List<int>;
            doneList.Add(0);

            if (doneList.Count == 2)    // Two items loaded
            {
                (PhoneApplicationService.Current.State["manualResetEvent"] as ManualResetEvent).Set();  // Signal that it's done
            }
        }
    };

    webClient.DownloadStringAsync(new Uri(url));
}

等待方法(在本例中为构造函数)

代码语言:javascript
复制
public SenastePage()
{
    InitializeComponent();

    if ((PhoneApplicationService.Current.State["doneList"] as List<int>).Count < 2)
    {
        (PhoneApplicationService.Current.State["manualResetEvent"] as ManualResetEvent).WaitOne();
    }
    SenasteArticleList.ItemsSource =  (PhoneApplicationService.Current.State["articleList"] as ArticleList).posts;
}

如果我在尝试访问构造函数之前等待,它很容易地传递If语句,并且不会被WaitOne捕获,但是如果我立即调用它,我就会被卡住,它永远不会返回.

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-20 19:07:46

必须不惜一切代价防止阻塞UI线程。特别是在下载数据时:不要忘记您的应用程序是在电话上执行的,它有一个非常不稳定的网络。如果数据需要两分钟才能加载,那么UI将被冻结两分钟。这将是一个糟糕的用户体验。

有很多方法可以防止这种情况发生。例如,您可以保持相同的逻辑,但在后台线程中等待,而不是在UI线程中等待:

代码语言:javascript
复制
public SenastePage()
{
    // Write the XAML of your page to display the loading animation per default
    InitializeComponent();

    Task.Factory.StartNew(LoadData);
}

private void LoadData()
{
    ((ManualResetEvent)PhoneApplicationService.Current.State["manualResetEvent"]).WaitOne();

    Dispatcher.BeginInvoke(() =>
    {
        SenasteArticleList.ItemsSource = ((ArticleList)PhoneApplicationService.Current.State["articleList"]).posts;

        // Hide the loading animation
    }
}

这只是一种快速而肮脏的方式来达到你想要的结果。您还可以使用任务重写代码,并在任务全部完成后使用Task.WhenAll触发操作。

票数 1
EN

Stack Overflow用户

发布于 2013-10-20 18:51:16

也许有一个逻辑问题。在SenastePage()构造函数中,只有当doneList计数小于2时,才会等待set事件。但是,在doneList计数等于2之前,不会触发set事件。在设置事件发生之前,您正在监听它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19481242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档