我有一个wpf应用程序,在主窗口中有一个文本框,用于在用户运行一个长过程时显示日志信息。Backgroundworker更新UI上的日志
<TextBox Grid.Row="1" Margin="10,10,10,10" AcceptsReturn="True" Name="txtLogging" TextWrapping="WrapWithOverflow"
Text="{Binding Path=LogText, Mode=TwoWay}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" />
public string LogText
{
get { return _logText; }
set
{
_logText = value;
OnPropertyChanged();
}
}
ui上的一个按钮启动了一个过程,该过程至少需要30秒,有时甚至需要几个小时。不用说,在后台工作者上运行它是首选。问题在于程序中的日志记录类正在UI线程上创建,并且必须在工作人员执行期间被访问,以使用当前正在发生的日志更新UI。
记录器看起来像这样;
using System;
using System.IO;
namespace BatchInvoice
{
public enum LoggingLevel
{
Verbose = 0,
Info = 1,
Warning = 2,
Error = 3
}
public sealed class Logger
{
string _logFile;
static Logger() { }
public bool LogToDataBase = false;
public bool LogToFile = true;
public bool LogToScreen = false;
private Logger()
{
//string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = Directory.GetCurrentDirectory();
filePath = filePath + @"\LogFiles";
string extension = ".log";
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
/*string currentDir = Environment.CurrentDirectory;
DirectoryInfo directory = new DirectoryInfo(currentDir);
string fullDirectory = directory.FullName;*/
string date = (DateTime.Now).ToString("yyyyMMddHHmmss");
_logFile = filePath + "\\" + date + extension;
minimumLoggingLevel = LoggingLevel.Info;
}
private LoggingLevel minimumLoggingLevel;
public static void SetMinimumLoggingLevel(LoggingLevel minimum)
{
Instance.minimumLoggingLevel = minimum;
}
public static LoggingLevel GetMinimumLoggingLevel()
{
return Instance.minimumLoggingLevel;
}
private static readonly Logger instance = new Logger();
public static Logger Instance
{
get
{
return instance;
}
}
public static void Write(string content)
{
using (StreamWriter fileWriter = File.AppendText(Instance._logFile))
{
fileWriter.WriteLine(content);
}
}
public static void Write(string content, LoggingLevel warningLevel)
{
if (Instance.minimumLoggingLevel <= warningLevel)
{
if (Instance.LogToFile)
{
using (StreamWriter fileWriter = File.AppendText(Instance._logFile))
{
fileWriter.WriteLine(warningLevel.ToString() + ": " + content);
}
}
if (Instance.LogToScreen)
ScreenLogging.Write(content, warningLevel);
if (Instance.LogToDataBase)
{
//enter database loggign code here.
}
}
}
}
}
using System.Windows;
using System.Windows.Controls;
namespace BatchInvoice
{
public class ScreenLogging
{
private static ScreenLogging _instance;
private ScreenLogging() { }
public static ScreenLogging Instance
{
get
{
if(_instance == null)
{
_instance = new ScreenLogging();
}
return _instance;
}
}
private TextBox _target;
public static void SetTarget(TextBox target)
{
Instance._target = target;
}
public static void Write(string content, LoggingLevel warningLevel)
{
//MessageBox.Show(content, warningLevel.ToString());
Instance._target.AppendText(warningLevel.ToString() + ": " + content + "\n");
}
}
}
(是的,有是screenlogging被分成不同的类的理由,但我真的希望我没有更改)我能做些什么,使这个日志类来电反思来自后台工作者的UI?我是否应该将LogText属性更改为从外部文件或这些行中读取?目前我没有实现后台工作,所以日志只显示任务完成后,但我需要能够监视其运行进度。当我尝试将它放入后台工作器时,它遇到了试图访问记录器的代码行时出现错误。
你可以使用Bgworker或任务和更新您的文本框中有只 – Firoz