在表单加载时启动后台线程
Start background thread on form load
需要向您寻求帮助,因为我现在为此苦苦挣扎了太久。
浏览了很多教程,但最终……一无所获。
所以,我有一个带有 GetServicesToList() 的 ServiceProcess class。此方法使用服务列表填充服务对象。
我现在正在做的是,我在应用程序 运行 时读取一个文件(包含服务)的缓存,并将数据显示在 datagridView 中。按下表单按钮时也会调用 GetServicesToList()。
由于服务器可用性问题,此任务最多需要 10 分钟。
在 BackgroundWorker class 的帮助下,我想要实现的是在 运行 时间启动此方法,每次完成后一遍又一遍地执行此操作以更新我的DataGridView 以及更新缓存(outputFile)。
所有这一切都没有用户被这个过程打断。
我已经在 BackgroundWord_DoWork() 中尝试调用此方法,但由于我的 ServiceProcess Class 使用 ServiceBase (class 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;
}
这是获取所有服务的方法。现在在设计class中,我想使用这个方法,因为线程或任务或后台工作所以这个方法将作为后台进程执行。不知道该怎么做...
并帮助您可视化应用程序本身...
我不完全确定你的目标,但是如果 GetServicesToList()
应该是 运行 在后台线程中,你不能只实现 async
/ await
?
public async Task<List<Service>> GetServicesToList()
{
return await Task.Run(() => {
// all your old code
});
}
当你调用它时
var serviceList = await GetServicesToList();
我假设你正在做某种数据绑定,所以当 serviceList
被水合时,只需将它传递给视图。
这是一个独立的概念。
using System;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
SimulateTenButtonClicks();
Console.ReadKey();
}
private static async void SimulateTenButtonClicks()
{
var foo = new Foo();
for (var i = 0; i < 10; i++)
{
var result = foo.DoStuff(i);
Console.WriteLine(await result);
}
}
public class Foo
{
public async Task<string> DoStuff(int i)
{
await Task.Delay(500); // simulate load
return await Task.Run(() =>
{
return String.Format("I have been hit {0} times", i);
});
}
}
}
}
需要向您寻求帮助,因为我现在为此苦苦挣扎了太久。 浏览了很多教程,但最终……一无所获。
所以,我有一个带有 GetServicesToList() 的 ServiceProcess class。此方法使用服务列表填充服务对象。
我现在正在做的是,我在应用程序 运行 时读取一个文件(包含服务)的缓存,并将数据显示在 datagridView 中。按下表单按钮时也会调用 GetServicesToList()。
由于服务器可用性问题,此任务最多需要 10 分钟。
在 BackgroundWorker class 的帮助下,我想要实现的是在 运行 时间启动此方法,每次完成后一遍又一遍地执行此操作以更新我的DataGridView 以及更新缓存(outputFile)。 所有这一切都没有用户被这个过程打断。
我已经在 BackgroundWord_DoWork() 中尝试调用此方法,但由于我的 ServiceProcess Class 使用 ServiceBase (class 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;
}
这是获取所有服务的方法。现在在设计class中,我想使用这个方法,因为线程或任务或后台工作所以这个方法将作为后台进程执行。不知道该怎么做...
并帮助您可视化应用程序本身...
我不完全确定你的目标,但是如果 GetServicesToList()
应该是 运行 在后台线程中,你不能只实现 async
/ await
?
public async Task<List<Service>> GetServicesToList()
{
return await Task.Run(() => {
// all your old code
});
}
当你调用它时
var serviceList = await GetServicesToList();
我假设你正在做某种数据绑定,所以当 serviceList
被水合时,只需将它传递给视图。
这是一个独立的概念。
using System;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
SimulateTenButtonClicks();
Console.ReadKey();
}
private static async void SimulateTenButtonClicks()
{
var foo = new Foo();
for (var i = 0; i < 10; i++)
{
var result = foo.DoStuff(i);
Console.WriteLine(await result);
}
}
public class Foo
{
public async Task<string> DoStuff(int i)
{
await Task.Delay(500); // simulate load
return await Task.Run(() =>
{
return String.Format("I have been hit {0} times", i);
});
}
}
}
}