便携式库中的异步编程

时间:2013-02-16 04:07:13

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

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

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中对数据执行某些操作。我知道我可以用两个嵌套的lambdas来做,但是我喜欢隐藏两个lambdas,这对于像我这样的老朋友来说更舒服。

请随意批评,对其他人来说,'和我一样受益。