C# winc中的异步绑定日志#

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); } }

我试图在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 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()相等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!
    }
}