在表单加载上启动后台线程

时间:2015-05-26 15:19:32

标签: c# multithreading winforms backgroundworker

需要求助你,因为我现在已经很久了。 已经完成了许多教程,但结果却......没有。

所以,我有一个带有GetServicesToList()的ServiceProcess类。此方法使用服务列表填充Service对象。

我现在在做什么,我正在app运行时读取一个缓存文件(带有服务),这会在datagridView中显示数据。按下表单按钮时也会调用GetServicesToList()。

由于服务器可用性问题,此任务最多需要10分钟。

在BackgroundWorker类的帮助下,我想要实现的是在运行时启动此方法,每次完成后重复执行以更新我的DataGridView以及更新缓存(outputFile)。 所有这一切都没有用户被这个过程中断。

我试图在BackgroundWord_DoWork()中调用此方法,但由于我的ServiceProcess类使用ServiceBase(类ServicesProcess:ServiceBase),我无法对BackgroundWorker声明此方法。

希望我已经表达了足够的细节,以便你们能够了解我正在努力实现的目标。如果有什么不清楚,请询问详细信息。

有人可以帮我解决这个问题吗?

public class ServicesProcess : ServiceBase, IEquatable<ServiceBase>
{
    private static string _machine = Services.GetServiceConfig();//ConfigurationManager.AppSettings.Get("machineName");
    private static List<Service> _servicesList;
    private static ServiceController[] _services;
    private List<ServiceController> _holder;
    private List<string> _configList;
    private static ObjectToSerialize _objectToSerialize;

    public List<Service> GetServicesToList()
    {
        //_services = ServiceController.GetServices(_machine);
        var result = MemoryCache.Default.Get(Name) as List<Service>;
        if (result != null)
            return result;

        try
        {

            _configList = new List<string>(Services.GetAllServicesConfig());
            _holder = new List<ServiceController>();
            foreach (string t in _configList)
            {
                _services = ServiceController.GetServices(t);
                _holder.AddRange(_services);
            }
        }
        catch (InvalidOperationException e)
        {

        }
        const string sPattern = "CSP";
        int i = 0;

        var cspServices = _holder.Where(x => x.DisplayName.Trim().StartsWith(sPattern)).ToList();

        _servicesList = new List<Service>();

        for (i = 0; i < cspServices.Count; i++)
        {
            Service obj = new Service
            {
                ServiceName = cspServices.ElementAt(i).DisplayName,
                ServiceVersion =
                    GetFileVersion(
                        GetFilePath(cspServices.ElementAt(i).ServiceName, cspServices.ElementAt(i).MachineName),
                        @"\\" + cspServices.ElementAt(i).MachineName + "\\"),
                ServiceStatus = cspServices.ElementAt(i).Status.ToString()
            };

            _servicesList.Add(obj);

        }

        _objectToSerialize = new ObjectToSerialize { Services = _servicesList };

        Serializer serializer = new Serializer();


        serializer.SerializeObject("outputFile.txt", _objectToSerialize);

        MemoryCache.Default.Set(Name, _servicesList, DateTimeOffset.Now.Add(new TimeSpan(0, 0, 30, 0)));

        return _servicesList;
    }

这是获得所有服务的方法。现在在设计类中,我想使用此方法,因为线程或任务或后台工作,因此此方法将作为后台进程执行。不知道怎么做......

并帮助您可视化应用程序本身...... enter image description here

1 个答案:

答案 0 :(得分:0)

我不完全确定您的目标,但如果GetServicesToList()应该在后台线程中运行,那么您是否只能实施async / {{1} }?

await

当你打电话时

public async Task<List<Service>> GetServicesToList()
{
    return await Task.Run(() => {
        // all your old code
    });
}

我假设您正在进行某种数据绑定,因此当var serviceList = await GetServicesToList(); 水合时,只需将其传递给视图。

这是一个独立的概念。

serviceList