小编Kev*_*aft的帖子

如何使用async/await OnNext/OnError/OnCompleted方法实现IObserver?

我正在尝试为System.Net.WebSocket编写一个扩展方法,它将使用Reactive Extensions(Rx.NET)将其转换为IObserver.你可以看到下面的代码:

public static IObserver<T> ToObserver<T>(this WebSocket webSocket, IWebSocketMessageSerializer<T> webSocketMessageSerializer)
{
    // Wrap the web socket in an interface that's a little easier to manage
    var webSocketMessageStream = new WebSocketMessageStream(webSocket);

    // Create the output stream to the client
    return Observer.Create<T>(
        onNext:      async message => await webSocketMessageStream.WriteMessageAsync(webSocketMessageSerializer.SerializeMessage(message)),
        onError:     async error   => await webSocketMessageStream.CloseAsync(WebSocketCloseStatus.InternalServerError, string.Format("{0}: {1}", error.GetType(), error.Message)),
        onCompleted: async ()      => await webSocketMessageStream.CloseAsync(WebSocketCloseStatus.NormalClosure, "Server disconnected")
    );
}
Run Code Online (Sandbox Code Playgroud)

这段代码有效,但我担心在onNext,onError和onCompleted lambdas中使用async/await.我知道这会返回一个async void lambda,这是不赞成的(有时候会引起我已经遇到的问题).

我一直在阅读Rx.NET文档以及互联网上的博客文章,我似乎无法找到在IObserver中使用async/await方法的正确方法(如果有的话).有没有正确的方法来做到这一点?如果没有,那么我该如何解决这个问题呢?

.net c# asynchronous task-parallel-library system.reactive

17
推荐指数
1
解决办法
3466
查看次数

iOS:在完成多个后台线程之前,不要从函数返回

这看起来应该很简单,但我遇到了很多麻烦.我有一个函数可以触发一些在后台运行并具有完成块的其他函数.我希望我的函数等到所有完成块都被返回之前被调用.

我无法控制我在后台执行的函数.否则我只是修改它以使用dispatch_async和我自己的队列,然后等待该队列完成.

我的情况看起来如何:

- (void)functionThatShouldBeSynchronous {
    for (int i = 0; i < 10; i++) {
        [self doSomethingInBackground:^{
            NSLog(@"completed!");
        }];
    }
    // How do I wait until all 10 threads have completed before returning?
}

- (void)doSomethingInBackground:(void(^)())completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        [NSThread sleepForTimeInterval:1.0f]; // Do stuff
        completion(); // Execute completion block
    });
}
Run Code Online (Sandbox Code Playgroud)

提前致谢.

objective-c ios

8
推荐指数
1
解决办法
3664
查看次数

如何在iPhone应用程序中处理身份验证

我目前正在开发我的第一个原生iPhone应用程序(虽然我有多年的Web开发经验).我在理解处理登录的最佳方式时遇到了一些困难,我正在寻找一些关于最佳方法的建议.我越想到登录过程中可能出现的所有问题,我的脑子就越想跳出脑袋.我对此非常感到沮丧,并且可以真正使用一些更有经验的iPhone开发人员的建议.在此先感谢您的帮助.

我的目标是在应用程序的第一个版本中支持Facebook Connect,然后在将来的版本中支持其他SSO服务(Twitter,Google等)以及我自己的用户帐户系统.目前的计划是在服务器上有一个MySQL表,如下所示:

users (id, nickname, facebook_id, ...)
Run Code Online (Sandbox Code Playgroud)

当用户第一次通过Facebook登录应用程序时,将在此表中为他们创建一个条目.您可能认为这不是必需的,但它将允许我稍后扩展到其他服务.例如,我可以这样做:

users (id, nickname, facebook_id, twitter_id, google_id, username, ...)
Run Code Online (Sandbox Code Playgroud)

此表将具有可用于facebook_id,twitter_id,google_id和用户名的可空字段.如果用户使用facebook登录,他们将拥有facebook_id.Twitter用户将拥有twitter_id,Google用户将拥有google_id,而我自己的用户将拥有用户名.无论他们使用什么登录系统,它们都将由我自己的id唯一标识.

所以我对用户帐户的后端实现很满意.我可以设置一个Web服务,应用程序可以调用该服务来创建/检索用户,验证登录等.没问题.

我遇到的问题是使用iPhone UI组件实现正确的登录流程.我的特定应用程序使用UITabBarController作为主导航.其中一个选项卡标有"我的帐户",其中包含有关当前登录用户的信息.如果用户单击"我的帐户"选项卡,则会显示一个用作子菜单的表视图.它有诸如"我的个人资料","设置"等一些选项.如果他们点击任何这些菜单项并且他们没有登录,那么我使用presentViewController功能弹出登录屏幕.他们点击"使用Facebook登录"并完成典型的Facebook授权流程.当他们完成该过程时,我使用dismissViewController删除登录页面并显示他们试图访问的页面.如果他们取消登录或登录失败,那么我在UINavigationController上使用popViewControllerAnimated将它们发送回"我的帐户"子菜单.对于那些难以想象的人,请查看亚马逊应用程序.它几乎完全相同(只需在您未登录时单击"更多"选项卡并尝试单击其下的一个菜单项).

这一切都很好,我很高兴.但是这里我感到困惑:

如果他们在"我的帐户"标签中的UINavigationController深入几层并且他们的登录会话到期,我该怎么办?

我们以Facebook登录为例.Facebook使用会话令牌来保持用户登录.令牌在一段时间后过期.假设用户导航到"我的帐户",然后单击"我的个人资料",然后点击"编辑",并显示一个屏幕,用户可以在其中编辑他们的个人资料信息.所以他们显然需要进行身份验证才能查看此页面.实际上,它们需要经过身份验证才能看到的页面深度为2-3级.现在让我们说他们被电话或其他东西打断了,忘记了他们在做什么.他们下次访问应用程序的时间是一周后他们的登录会话已过期.我可以通过几种方式解决这个问题.他们似乎对我来说都不是很好.

解决方案#1

Facebook SDK将自动调用AppDelegate类上的方法,该方法通知我过期的会话.由于我在AppDelegate级别收到会话到期通知,因此我不知道用户当前正在查看哪个页面以及是否需要对其进行身份验证才能使用它.为了解决这个问题,我可以让所有需要登录的ViewControllers扩展"ProtectedViewController"类或者指示用户应该登录以查看该页面的内容.然后,当AppDelegate被通知会话到期时,它将尝试找出当前的ViewController是什么,并检查它是否扩展了"ProtectedViewController".如果是,则显示登录屏幕.如果用户成功登录,则一切都正常进行.如果没有,则将用户返回到他们必须从头开始的应用程序的第一个屏幕.这很糟糕,因为用户将丢失他们已经输入的任何内容,但我认为没有办法通过此解决方案来避免它.

解决方案#2

忽略AppDelegate级别的会话过期事件,而是执行此操作:在执行任何需要用户登录的操作之前(例如,当用户在"编辑个人资料"页面上单击"保存"时),检查他们是否仍然登录.如果不是,则显示登录屏幕.如果用户登录失败,则将其发送回开始屏幕.这个解决方案很难解决问题,因为我必须检查用户在应用程序的受保护区域内执行的所有操作 - 当他们查看页面时,单击按钮时 - 几乎所有内容.

如果用户无法重新进行身份验证,我还是希望避免将用户一直发送回应用的开始屏幕.相反,在这种情况下,我更愿意将用户备份UINavigationController发送到"我的帐户"菜单 - 这是最近的页面,不需要登录.当然,我可以对其进行硬编码,但我正在寻找一种可以更自然地工作的解决方案/模式,并且我可以在其他应用程序中重复使用.

我真的很感激一些指导.当然,我不是世界上第一个需要解决这个问题的人.不幸的是,谷歌没有太多帮助.

谢谢.

编辑:另一个想法是子类UIViewController(例如"ProtectedViewController")并实现"viewWillAppear"方法.在这个方法中,我可以检查用户是否已登录.如果没有,那么我将滑动登录页面.但是,当他们登录失败时,我仍然不知道如何处理这个案子.但是,此解决方案存在一个问题:如果用户的会话在使用应用程序时到期,那么在下次单击新视图之前,我不会重新对其进行身份验证.如果他们已经在查看"编辑"页面并单击"保存"按钮,则不会重新进行身份验证.但也许这是更接近解决方案的一步.

iphone facebook ios

6
推荐指数
1
解决办法
1537
查看次数

像GrabCut这样的图像分割算法可以在iPhone GPU上运行吗?

我一直在研究iPhone上的GrabCut算法(在OpenCV中实现)。表演很恐怖。即使在模拟器上运行大约800x800的图像也要花费大约10-15秒的时间。在我的手机上,它运行了几分钟,最终耗尽了内存,并崩溃了(iPhone 4)。我敢肯定,如果我用C编写自己的算法版本,可能会做一些优化,但是我感到没有任何优化可以使它接近可用状态。我已经在一些学术论文中挖掘了一些性能指标,甚至他们在多核1.8 GHz CPU上看到了30秒的运行时间。

因此,我唯一的希望就是GPU,而我对此一无所知。到目前为止,我已经对OpenGL ES进行了一些基础研究,但这是一个非常深入的主题,我不想浪费数小时或数天来学习基本概念,只是想知道我是否正在学习正确的道路。

所以我的问题是双重的:

1)可以在GPU上运行类似GrabCut的东西吗?如果是这样,除了“学习OpenGL ES”之外,我还希望有一个起点。理想情况下,我想知道我需要特别注意哪些概念。请记住,我没有使用OpenGL的经验,也没有图像处理的经验。

2)即使这种算法可以在GPU上运行,我应该期望什么样的性能提升?考虑到当前运行时间大约是CPU的最佳时间30秒,GPU似乎不太可能在运行时间中投入足够多的凹痕来使算法有用。

编辑:为使算法“有用”,我认为它必须在10秒或更短的时间内运行。

提前致谢。

gpu image-processing ios

5
推荐指数
1
解决办法
2130
查看次数

是否可以使用 xUnit.net“继承”测试?

我有一个名为 EventManager 的具体类和一个名为 ScheduledEventManager 的子类。我希望 ScheduledEventManager 必须通过与 EventManager 相同的测试以及一些额外的测试。xUnit.net 可以做到这一点吗?

编辑:我刚刚意识到我的情况比这更复杂一点。我使用嵌套类来使我的测试更有条理。例子:

public class EventManagerTests
{
    public class WhenAnEventIsFired
    {
        [Fact]
        void ItNotifiesSubscribers()
        {
            // Perform the test
        }
    }
}

public class ScheduledEventManagerTests
{
    // How to I inherit the above tests since they are in nested classes?
}
Run Code Online (Sandbox Code Playgroud)

在我看来这是不可能的,但也许你们中的一位天才知道一些我不知道的事情。

c# xunit.net

4
推荐指数
2
解决办法
2491
查看次数

Moq:在不返回值的方法上调用方法后的回调

我目前正在使用 Moq 库进行单元测试。Moq 使我能够在模拟对象上的方法调用之前之后注册回调如下所示:

Mock<IMyClass> mock = new Mock<IMyClass>();
mock.Setup(o => o.MyMethod())
  .Callback(() => Console.WriteLine("BEFORE!"))
  .Returns(true)
  .Callback(() => Console.WriteLine("AFTER!"));
Run Code Online (Sandbox Code Playgroud)

但是,如果MyMethod不返回值(即它有一个void返回类型),那么我只能像这样设置一个回调:

mock.Setup(o => o.MyMethod())
  .Callback(() => Console.WriteLine("BEFORE!"));
Run Code Online (Sandbox Code Playgroud)

如代码中所述,此回调在调用方法之前发生。似乎没有任何其他选项可以调用方法指定第二个回调。

这可能吗?文档中似乎没有关于它的任何内容。我错过了什么吗?

c# unit-testing moq

4
推荐指数
1
解决办法
3941
查看次数

使用我的NuGet包分发可重用测试类有哪些选择?

我目前有两个项目的解决方案设置:

MySolution
- MyClassLibrary
- MyClassLibrary.Tests
Run Code Online (Sandbox Code Playgroud)

MyClassLibrary项目作为NuGet包分发.测试项目包含我目前未与NuGet包一起分发的所有单元测试.

问题是在MyClassLibrary中,我的一个类接受一个I​​MyRepository作为构造函数参数(允许依赖注入).然后,我在MyClassLibrary.Tests项目中设置了一个名为IMyRepositoryTests的抽象测试类设置.目的是当你编写自己的IMyRepository实现时,你可以编写一个简单地继承自IMyRepositoryTests的测试类,并传入你的具体类的实例,所有测试都将为你完成.

所以结构看起来像这样:

Solution
- MyClassLibrary
-- MyServiceClass(IMyRepository repository)
-- IMyRepository
- MyClassLibrary.Tests
-- MySericeClassTests
-- IMyRepostoryTests (abstract)
Run Code Online (Sandbox Code Playgroud)

问题是测试项目没有与NuGet包一起分发,所以如果有人想要对他们具体的IMyRepository实现进行单元测试,他们将不得不编写自己的所有测试,这些测试(1)不会利用我已经为他们编写的测试代码和(2)可能不符合我对IMyRepository的规范.

如果我将IMyRepositoryTests移动到MyClassLibrary项目,那么该项目将依赖于我的单元测试框架(Xunit和Moq).这为没有进行单元测试的人增加了不必要的依赖关系.

如果我使用NuGet包发送测试项目,那么我会创建相同的问题,而且看起来像使用单元测试发送NuGet包似乎不是标准做法.

我可以将Tests项目作为单独的NuGet包发布,但这看起来也很奇怪.

我还缺少其他选择吗?

.net c# unit-testing visual-studio nuget

1
推荐指数
1
解决办法
225
查看次数