简体   繁体   English

C#-如何更改辅助线程中进度条的值

[英]C# - How to change value of a progress bar in a secondary thread

In my program I import millions of records to a SQL Server database with the help of SqlBulkCopy class. 在我的程序中,借助于SqlBulkCopy类,将数百万条记录导入到SQL Server数据库中。 Since this is a heavy lifting it takes quite some time. 由于这是一项繁重的工作,因此需要相当长的时间。 While the process goes on I want to show the progress in a progressbar control. 当过程继续进行时,我想在进度条控件中显示进度。 To be notified for the rows copied I've done this: 要通知复制的行,我这样做:

.......
bulkCopy.NotifyAfter = 2000;
bulkCopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
.......

Now in the bulkCopy_SqlRowsCopied method I want to change the value of the progress bar. 现在,在bulkCopy_SqlRowsCopied方法中,我想更改进度栏的值。 But I think I need to make it on a seperate thread. 但是我认为我需要在单独的线程上创建它。 How can I do this? 我怎样才能做到这一点?

You can have one extension class, like 您可以拥有一个扩展类,例如

public static class ControlExtensions
{
    public static void Invoke(this Control control, Action action)
    {
        if (control.InvokeRequired) control.Invoke(new MethodInvoker(action), null);
        else action.Invoke();
    }
 }

Now when ever and where ever you want to update status of progress bar, you can do 现在,无论何时何地您想要更新进度条的状态,您都可以

progressBar.Invoke(() => { progressBar.PerformStep(); };

Hope this works for you. 希望这对您有用。

You could execute your copy in a BackgroundWorker and use ReportProgress to update your progressbar... 您可以在BackgroundWorker中执行您的副本,并使用ReportProgress更新进度条...
You can find an example at http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx . 您可以在http://msdn.microsoft.com/zh-cn/library/cc221403(v=vs.95).aspx中找到示例。

The use of a BackgroundWorker for time-consuming operations is good because your UI (with the main thread) is free to be updated/refreshed, making user experience better. 使用BackgroundWorker进行耗时的操作很好,因为您的UI(带有主线程)可以自由更新/刷新,从而使用户体验更好。

For non-collection properties WPF will marshall the value on to the UI thread for you. 对于非集合属性,WPF将为您将值编组到UI线程上。 So if you have a ViewModel with a progress property that raises the PropertyChanged event you can bind your ProgressBar to the ProgressBar. 因此,如果您的ViewModel带有一个引发PropertyChanged事件的progress属性,则可以将ProgressBar绑定到ProgressBar。

For this to work, your ViewModel instance should not be a DependencyObject (but that is a bad idea for so many reasons). 为此,您的ViewModel实例不应是DependencyObject(但这是个坏主意,原因有很多)。 This way you can reference it from your background thread and set the Progress property. 这样,您可以从后台线程引用它并设置Progress属性。

Using the Invoke() Method of the ProgressBar Control in your EventHandler "bulkCopy_SqlRowsCopied", make sure you set the NotifyAfter property of the SqlBulkCopy class to an amount that would reflect some form of percentage. 在EventHandler“ bulkCopy_SqlRowsCopied”中使用ProgressBar控件的Invoke()方法,确保将SqlBulkCopy类的NotifyAfter属性设置为可以反映某种百分比形式的数量。

Now in the bulkCopy_SqlRowsCopied method I want to change the value of the progress bar. 现在,在bulkCopy_SqlRowsCopied方法中,我想更改进度栏的值。 But I think I need to make it on a seperate thread. 但是我认为我需要在单独的线程上创建它。 How can I do this? 我怎样才能做到这一点?

If you are using .Net 4.0 you could start your bulk copy in a Task, other versions you could use the ThreadPool, create your own thread 如果您使用的是.Net 4.0,则可以在Task中启动批量复制,其他版本则可以使用ThreadPool,创建自己的线程

Task.Factory.StartNew(MyBulkCopyMethod);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM