显示进度与reative扩展linqpad还原数据库 [英] Display progress while restoring database in linqpad with reative extensions

查看:270
本文介绍了显示进度与reative扩展linqpad还原数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的C#代码

var databaseRestore = new Microsoft.SqlServer.Management.Smo.Restore();
//databaseRestore.PercentComplete += CompletionStatusInPercent;
//databaseRestore.PercentCompleteNotification = 10;
//databaseRestore.Complete += Restore_Completed;

...

var complete = Observable
    .FromEventPattern(databaseRestore, "Complete")
    .Select(x=>x.EventArgs as ServerMessageEventArgs)
    .Select(x=>x.Error.Message)
    .Take(1)
    .DumpLive("Complete");

var percentComplete = Observable
    .FromEventPattern(databaseRestore, "PercentComplete")
    .Select(x=>x.EventArgs as PercentCompleteEventArgs)
    .Select(x=>x.Percent)
    .TakeUntil(complete)
    .DumpLive("PercentComplete");

...

databaseRestore.SqlRestore(server);

如果我运行这一点,首先来始终从处理程序的输出(如果我去掉它们)。

If I run it this, first comes always the output from handlers (if I uncomment them).

然后第一,Linqpad显示了

Then first, Linqpad shows the "Live Observables" result tab with


    完成可观的,已经完成和最终结果的消息
  1. 。PERCENTCOMPLETE,仍在等待,并以 - (还没有条目)

我想只是从使用反应extenxions事件来走什么。
首先应该来了PERCENTCOMPLETE可观察与实际进度更新。
然后完成用最后的消息

What I want is just to come away from events using reactive extenxions. First should come the "PercentComplete" observable updated with actual progress. Then "Complete" with final message.

这样的问题:如何设置了观测正确

The question: how do I set up the observables properly?

推荐答案

我的猜测是,这是DumpLive()在主线程中如何使用一个调度程序故障。

My guess is this is the fault of how DumpLive() uses a Dispatcher on the main thread.

是在运行主线程上的数据库恢复或阻塞主线程等待完成信号?

Are you running the database restore on the main thread, or blocking the main thread waiting for a completion signal?

我试验了一下,跑了一个可观察到与一个在后台线程DumpLive() - 如果主线程被阻塞(如:带等待或Thread.sleep代码)的用户界面没有更新

I experimented a bit and ran an Observable on a background thread with a DumpLive() - if the main thread was blocked (e.g. with a Wait or a Thread.Sleep) the UI did not update.

即使它是在不同的线程,似乎DumpLive()只能更新在主线程的UI。我的猜测是,它需要渲染与主线程相关的调度更新。

Even if it's on a different thread, it seems DumpLive() can only update the UI on the main thread. My guess it that it needs to render updates on a Dispatcher associated with the main thread.

在使用DumpLive LINQPad不会终止执行,直到完成观测,因此,如果您对主线程阻塞任何代码中删除它,看看它是否工作呢。

When using DumpLive LINQPad won't terminate execution until the observables complete, so if you have any blocking code on main thread remove it and see if it works then.

下面是我的实验代码。只要你在下面的例子中为 DumpLive()子句添加,你会看到阻塞行为:

Here's my experimental code. As soon as you add in either DumpLive() clause in the example below, you'll see the blocking behaviour:

void Main()
{
    Task.Run(() => {
    var progressor = new Progressor();
    var complete = Observable
        .FromEventPattern(
        h => progressor.Complete += h,
        h => progressor.Complete -= h)
        .Select(_ => "Complete")
        .Take(1);
        // append this to see blocking
        //.DumpLive();

        complete.Subscribe(Console.WriteLine);


    var percentComplete = Observable
        .FromEventPattern<PercentCompleteEventArgs>(
        h => progressor.PercentComplete += h,
        h => progressor.PercentComplete -= h)
        .TakeUntil(complete)
        .Select(i => "PercentComplete " + i.EventArgs.PercentComplete);
        // append this to see blocking
        // .DumpLive();

        percentComplete.Subscribe(Console.WriteLine);
    });

    Thread.Sleep(5000);
}

public class Progressor
{
    public Progressor()
    {
        Observable.Interval(TimeSpan.FromSeconds(1)).Take(10)
            .Subscribe(
            i => RaisePercentComplete(((int)i+1) * 10),
            () => RaiseComplete());
    }

    private void RaiseComplete()
    {
        var temp = Complete;
        if(temp != null)
        {
            temp(this, EventArgs.Empty);
        }
    }

    private void RaisePercentComplete(int percent)
    {
        var temp = PercentComplete;
        if(temp != null)
        {
            temp(this, new PercentCompleteEventArgs(percent));
        }
    }

    public event EventHandler Complete;
    public event EventHandler<PercentCompleteEventArgs> PercentComplete;
}

public class PercentCompleteEventArgs : EventArgs
{
    public int PercentComplete { get; private set; }

    public PercentCompleteEventArgs(int percent)
    {
        PercentComplete = percent;
    }
}

这篇关于显示进度与reative扩展linqpad还原数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆