C# winc中的异步绑定日志#
我试图在WinForm中添加一些日志,同时查找一些C# winc中的异步绑定日志#,c#,multithreading,winforms,C#,Multithreading,Winforms,我试图在WinForm中添加一些日志,同时查找一些 private async Task SaveChunk(DataChunkSaver chunk) { int i = 0; int step = 10; while (chunk.saveChunk(i, step)) { i += step; AddLog(chunk.Log); } }
private async Task SaveChunk(DataChunkSaver chunk)
{
int i = 0;
int step = 10;
while (chunk.saveChunk(i, step))
{
i += step;
AddLog(chunk.Log);
}
}
其中: private async Task AddLog(string text)
{
LogBulider.AppendLine(text);
LogBox.Text = LogBulider.ToString();
}
AndLogBulider是一个简单的全局StringBulider。
问题是,当我使用SaveChunk任务启动按钮时,我的表单会冻结,这样我可以在完成所有操作后看到日志框,并且我希望在chunk.SaveChunk的每个步骤后都能播放它。我尝试用几种方法解雇他们,但我无法处理
我做错了什么
private async void button2_Click(object sender, EventArgs e)
{
await Task.Factory.StartNew(() => SaveChunk(chunk));
Task T = SaveChunk(chunk);
// none of these works, I also tried few other
//ways to do it, but none prevents my winForm from freezing
}
我试图使用
进度
修改您的代码:
private async void按钮2\u单击(对象发送方,事件参数e)
{
var progress=新进度(msg=>
{
LogBulider.AppendLine(msg);
LogBox.Text=LogBulider.ToString();
});
等待任务。运行(()=>SaveChunk(chunk,progress));
}
及
private async Task SaveChunk(DataChunkSaver chunk,IProgress progress)
{
int i=0;
int步长=10;
while(chunk.saveChunk(i,步骤))
{
i+=阶跃;
进度?.Report(chunk.Log);//始终使用进度,就好像它可以为空一样!
}
}
您是否尝试了任务。运行(()=>SaveChunk(chunk))代码>(不等待!)?顺便说一下,您不应该从非GUI线程修改GUI。您是否考虑过a)使用BackgroundWorker或b)IProgress?并确保使用wait AddLog(chunk.Log)
;在您的SaveChunk方法中。使用异步方法而不使用wait可能会产生不想要的行为。@RoelantM我认为他应该通过一个IProgress来“记录”。他正在尝试从线程池线程修改GUI。然后我收到错误,因为有多个任务试图访问名为“LogBox”的totextBox。我建议您阅读以下内容:始终使用进度,就像它可以为null一样!-为什么在另一个私有方法中调用私有方法SaveChunk
按钮2\u用正确实例化的Progress
实例单击?@Fabio这只是一个指导原则。当您提供带有便利重载的异步API时(一个只包含进度,一个只包含CancelationToken,一个不包含两者),建议使用null
为“无进度”,使用CancelationToken.NONE为“无取消”中继到完整版本(包含进度和令牌)。因此,您必须始终将进度视为可能为空。在这种特殊情况下,您也可以忽略它,但这并不有害,是吗?而且您以后还可以在其他地方使用私有函数,在这些地方您不希望取得进展。是的,也许只有我一个人,但我在使用progress时总是想到“这是可选的”。对不起,我自己从来没有使用过IProgress
,这就是问题的原因。我发现?
操作符提供了某种“陷阱”-我更喜欢确保null
引用不会被传递,并消除可能的nullchecking@Fabio确切地说,progress?.Report()
与if(progress!=null)progress.Report()相等当然,您也可以将“静默进程”作为NullObject模式。我不是反对这一点。
private async void button2_Click(object sender, EventArgs e)
{
var progress = new Progress<string>(msg =>
{
LogBulider.AppendLine(msg);
LogBox.Text = LogBulider.ToString();
});
await Task.Run(() => SaveChunk(chunk, progress));
}
private async Task SaveChunk(DataChunkSaver chunk, IProgress<string> progress)
{
int i = 0;
int step = 10;
while (chunk.saveChunk(i, step))
{
i += step;
progress?.Report(chunk.Log); // Always use progress as if it could be null!
}
}