小编Jes*_*det的帖子

从头开始实现IObservable <T>

Reactive Extensions带有许多辅助方法,用于将现有事件和异步操作转换为可观察对象,但是如何从头开始实现IObservable <T>?

IEnumerable有一个可爱的yield关键字,使其实现起来非常简单.

实现IObservable <T>的正确方法是什么?

我需要担心线程安全吗?

我知道有人支持在特定的同步上下文中回调,但这是否是我作为IObservable <T>作者需要担心或者以某种方式内置的内容?

更新:

这是Brian的F#解决方案的C#版本

using System;
using System.Linq;
using Microsoft.FSharp.Collections;

namespace Jesperll
{
    class Observable<T> : IObservable<T>, IDisposable where T : EventArgs
    {
        private FSharpMap<int, IObserver<T>> subscribers = 
                 FSharpMap<int, IObserver<T>>.Empty;
        private readonly object thisLock = new object();
        private int key;
        private bool isDisposed;

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing && !isDisposed)
            {
                OnCompleted();
                isDisposed = true;
            }
        }

        protected void OnNext(T value)
        {
            if (isDisposed) …
Run Code Online (Sandbox Code Playgroud)

c# system.reactive

38
推荐指数
3
解决办法
1万
查看次数

Reactive Extensions(Rx)+ MVVM =?

用于解释Reactive Extensions(Rx)功能的一个主要示例是将现有鼠标事件组合成一个表示鼠标拖动过程中增量的新"事件":

var mouseMoves = from mm in mainCanvas.GetMouseMove()
                 let location = mm.EventArgs.GetPosition(mainCanvas)
                 select new { location.X, location.Y};

var mouseDiffs = mouseMoves
    .Skip(1)
    .Zip(mouseMoves, (l, r) => new {X1 = l.X, Y1 = l.Y, X2 = r.X, Y2 = r.Y});

var mouseDrag = from _  in mainCanvas.GetMouseLeftButtonDown()
                from md in mouseDiffs.Until(
                    mainCanvas.GetMouseLeftButtonUp())
                select md;
Run Code Online (Sandbox Code Playgroud)

资料来源: Matthew Podwysocki的反应框架系列介绍.

在MVVM中,我通常努力使我的.xaml.cs文件尽可能为空,并且使用viewmodel中的命令从视图中连接事件的一种方法纯粹是在标记中使用一种行为:

<Button Content="Click Me">
    <Behaviors:Events.Commands>
        <Behaviors:EventCommandCollection>
            <Behaviors:EventCommand CommandName="MouseEnterCommand" EventName="MouseEnter" />
            <Behaviors:EventCommand CommandName="MouseLeaveCommand" EventName="MouseLeave" />
            <Behaviors:EventCommand CommandName="ClickCommand" EventName="Click" />
        </Behaviors:EventCommandCollection>
    </Behaviors:Events.Commands>
</Button>
Run Code Online (Sandbox Code Playgroud)

资料来源: …

mvvm reactive-programming system.reactive

29
推荐指数
3
解决办法
1万
查看次数

Nuget - 打包一个包含多个项目的解决方案(针对多个框架)

假设我有以下解决方案,同一个代码的多个版本,每个版本都针对不同的框架,我想从中生成一个nuget包.

SharedLib.sln
  SharedLib.Net35.csproj
    packages.config
  SharedLib.Net40.csproj
    packages.config
  SharedLib.Phone.csproj
    packages.config
  SharedLib.SL4.csproj
    packages.config
Run Code Online (Sandbox Code Playgroud)

预期的nupkg具有以下结构

SharedLib.1.0.nupkg
  lib/net35/SharedLib.dll
  lib/net40/SharedLib.dll
  lib/sl4-wp/SharedLib.dll
  lib/sl4/SharedLib.dll
Run Code Online (Sandbox Code Playgroud)

nuget.exe pack SharedLib.SL4.csproj 将自动确定目标框架是SilverLight4并将二进制文件放入 lib/sl4

我知道我可以添加一个SharedLib.SL4.nuspec带有一个<file>部分的文件来包含来自其他项目的二进制文件,但是有没有办法让nuget自动将组合的解决方案输出放到适当的结构中(并且还检测来自所有项目的packages.config中的依赖项?

nuget

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

如何使Binding尊重DependencyProperty值强制?

我有一个带有CoerceValueCallback的DependencyProperty的控件.此属性绑定到模型对象上的属性.

将控件属性设置为导致强制的值时,Binding会将未校正的值推送到模型对象.控件上的属性值被正确强制.

如何让Binding将强制值推送到模型对象?

void Initialize()
{
    UIObject ui = new UIObject();
    ModelObject m = new ModelObject();
    m.P = 4;

    Binding b = new Binding("P");
    b.Source = m;
    b.Mode = BindingMode.TwoWay;
    Debug.WriteLine("SetBinding");
    // setting the binding will push the model value to the UI
    ui.SetBinding(UIObject.PProperty, b);

    // Setting the UI value will result in coercion but only in the UI.
    // The value pushed to the model through the binding is not coerced.
    Debug.WriteLine("Set to -4");
    ui.P …
Run Code Online (Sandbox Code Playgroud)

wpf binding dependency-properties coercion

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

保护应用程序和后台代理之间的共享isosorage数据

根据MSDN前台应用程序和后台代理之间的通信,通过隔离存储中的文件应该受到Mutex的保护.

我能找到的唯一的文章介绍了如何做,这是这一个由迪娜·贝瑞.但是,她似乎只用Mutex保护读取而不是写入.

这样做的正确方法是什么?

c# mutex isolatedstorage windows-phone-7 background-agent

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

如何让IObservable在订阅时推送最新值

通常,当您订阅值的更改时,您也有兴趣知道初始值.我希望我的IObservable缓存最新(或初始)值并在订阅时推送该值.

当使用普通事件时,我经常会得到看起来像的代码

x.SomeEvent += SomeEventHandler;
SomeEventHandler(x, EventArgs.Empty);
Run Code Online (Sandbox Code Playgroud)

使用IObservable我希望用推送初始值的东西包装事件.如果我有多个订阅者,他们应该在订阅时收到最新的值我有一些代码,如果我在创建IObservable之后立即订阅,但是如果事件在订阅之前触发则不会:

class Program
{
    static void Main()
    {
        var s = new Source { Value = 1 };
        var values = Observable.Return(s.Value).Concat(
            Observable.FromEvent(
                h => s.ValueChanged += h,
                h => s.ValueChanged -= h)
            .Select(_ => s.Value));
        using (values.Subscribe(Console.WriteLine))
        {
            s.Value = 2; // prints 1,2 as expected
        }
        using (values.Subscribe(Console.WriteLine))
        {
            s.Value = 3; // prints 1,3 - expected 2,3
        }
    }
}

class Source
{
    private int _value;
    public int Value
    { …
Run Code Online (Sandbox Code Playgroud)

c# system.reactive

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

在javascript中使用任意根制作相对url绝对值

假设我在不同域(mydomain.com)上的页面上,并且相对URL仅存在于代码中(不在DOM中)

如何在javascript中完全组合两个任意网址?

var a = 'http://example.com/some/path/';
var b = '../other/path/';
var c = magicUrlCombine(a,b);
assert(c == 'http://example.com/some/other/path/');
Run Code Online (Sandbox Code Playgroud)

它也应该有效

var a = 'http://example.com/some/path/';
var b = 'http://pink-unicorns.com/some/other/path/';
var c = magicUrlCombine(a,b);
assert(c == 'http://pink-unicorns.com/some/other/path/');
Run Code Online (Sandbox Code Playgroud)

编辑:

我正在寻找一个完全通用的功能,用于将绝对URL与任意URL组合.与浏览器用于解析链接的逻辑相同,但用于不在页面HTML中和/或不相对于当前location.href的URL.

var a = 'http://example.com/a/b/c/';
var b = '../d/e/';
assert(c == 'http://example.com/a/b/d/e/')
Run Code Online (Sandbox Code Playgroud)

要么

var b = '/f/g/';
assert(c == 'http://example.com/f/g/')
Run Code Online (Sandbox Code Playgroud)

要么

var b = 'http://jquery.com/h/i/';
assert(c == 'http://jquery.com/h/i/')
Run Code Online (Sandbox Code Playgroud)

编辑2:

node.js有一个具有正确功能的url模块,但我还没有找到一种在客户端重用它的好方法.(如何在客户端使用node.js模块系统)

我设法通过破解我的方式使其工作,但这不是一个真正的解决方案我觉得放入生产网站很舒服.Hackety hack

javascript url

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