【问题标题】:async programming in portable library可移植库中的异步编程
【发布时间】:2013-02-01 03:26:40
【问题描述】:

我对新的异步内容感到非常困惑。我有一个可移植库实现我的模型,其中包含一些具有虚拟功能的类,我希望在 ASP .NET、WPF、Windows Store、Silverlight 5 和 Windows Phone 8 中使用。它们可能针对 WCF 功能、CSharp SQLite,或者在平台中被覆盖- 本地文件的特定库。

既然同步编程在 Windows 应用商店世界中不受欢迎,我该如何设置它?我尝试在虚拟函数的可移植库中添加异步关键字等,但它说我没有必要的框架。如何在不重写的情况下重用这个库? OOP 编程现在完全死了吗?

【问题讨论】:

  • 什么是OOB编程?那是穷人版的 OOP 吗?
  • 无论如何,新的异步方式并没有改变任何东西;您仍然可以按原样使用您的库,特别是如果没有任何调用花费超过 50 毫秒。这是 Microsoft 的指标,其框架中只有 10% 的调用符合该指标,因此被编写为异步的。剩下的 90% 还是不错的 ole 普通同步方法。
  • 对不起,我是说面向对象的。经过 15 小时的编程,大脑已经被烧得焦头烂额了。
  • 为了展开,我很高兴在使用 Thread 进行操作之前,然后(对于 Silverlight 和 WP)使用 Dispatch。 Windows 应用商店中的什么等价物不会破坏性能?例如,假设我有一个用于单击按钮的事件处理程序,是否可以使用 lambda 表达式来调用需要很长时间的函数,但仍会立即从事件处理程序返回?

标签: .net async-await portable-class-library


【解决方案1】:

VS 很乐意在面向 .NET 4.5 和 Windows Store 的可移植库中允许 async。如果您需要其他平台(尤其是 .NET 4.0 和 Silverlight 5),则需要安装 Microsoft.Bcl.Async

如果您需要参考,source for my AsyncEx library 可用;核心程序集是一个依赖于 Microsoft.Bcl.Async 的可移植库。

【讨论】:

    【解决方案2】:

    我解决它的方法是使用我从以前版本改编的帮助类。基本上:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Windows.UI.Core;
    using Windows.UI.Xaml;
    
    namespace JTModelsWinStore.Local
    {
        public delegate void UseDataDelegate(DataCoordinator data);
        public delegate bool GetDataDelegate(DataCoordinator data);
    
        public class DataCoordinator
        {
            public DependencyObject Consumer;
            public GetDataDelegate GetDataFunction;
            public UseDataDelegate UseDataFunction;
            public bool GetDataSucceeded;
            public Exception ErrorException;
            public string ErrorMessage;
    
            public DataCoordinator(
                DependencyObject consumer,
                GetDataDelegate getDataFunction,
                UseDataDelegate useDataFunction)
            {
                Consumer = consumer;
                GetDataFunction = getDataFunction;
                UseDataFunction = useDataFunction;
                GetDataSucceeded = false;
                ErrorException = null;
                ErrorMessage = null;
            }
    
            public Task GetDataAsync()
            {
                GetDataSucceeded = false;
    
                Task task = Task.Factory.StartNew(() =>
                {
                    if (GetDataFunction != null)
                    {
                        try
                        {
                            GetDataSucceeded = GetDataFunction(this);
                        }
                        catch (Exception exception)
                        {
                            GetDataSucceeded = false;
                            ErrorException = exception;
                            ErrorMessage = exception.Message;
                        }
                    }
    
                    if (UseDataFunction != null)
                    {
                        if (Consumer != null)
                        {
                            var ignored = Consumer.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                UseDataFunction(this);
                            });
                        }
                        else
                            UseDataFunction(this);
                    }
                });
                return task;
            }
        }
    }
    

    然后在 Windows 商店代码中:

    private async void ItemView_ItemClick(object sender, ItemClickEventArgs e)
    {
        DataCoordinator data = new DataCoordinator(this, Logon, LogonCompleted);
        await data.GetDataAsync();
    }
    
    private bool Logon(DataCoordinator data)
    {
        LoggedOnUserID = ServiceClient.LogOn(UserName, Password);
    
        if (LoggedOnUserID == null)
        {
            UserName = "AnonymousUser";
            Password = "";
    
            if (!String.IsNullOrEmpty(ServiceClient.ErrorMessage))
                data.ErrorMessage = "Log on failed.";
    
            return false;
        }
    
        if (!String.IsNullOrEmpty(ServiceClient.ErrorMessage))
        {
            data.ErrorMessage = ServiceClient.ErrorMessage;
            return false;
        }
    
        return true;
    }
    
    private void LogonCompleted(DataCoordinator data)
    {
        if (data.GetDataSucceeded && LoggedOnUserID != null)
            pageTitle.Text = "Logged On";
        else
            pageTitle.Text = "LogOn Failed";
    }
    

    我为助手提供了两种功能,一种用于获取数据(慢速),另一种用于在 UI 中处理数据。我知道我可以在两个嵌套的 lambda 中做到这一点,但我喜欢隐藏两个 lambda,这对于像我这样的老前辈来说更舒服。

    为了他人和我自己的利益,请随时批评它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-16
      相关资源
      最近更新 更多