C# TextView.Buffer上发生System.AccessViolationException异常

C# TextView.Buffer上发生System.AccessViolationException异常,c#,mono,monodevelop,gtk#,C#,Mono,Monodevelop,Gtk#,我试图用Gtk图形用户界面在C#上显示一些文本,每秒一行。 文本位于.txt文件中,每行有4个整数 但是当我在DragonFly BSD上编译它时,前一两行在textbox上完美地显示出来,但是程序停止了,并且出现了SIGABRT和SIGSEGV错误 所以我在Windows上编译了相同的代码,它有一个错误:“System.AccessViolationException”异常或类似的错误 我检查了“允许不安全代码”,但结果是一样的 async void DisplayText(string Fi

我试图用Gtk图形用户界面在C#上显示一些文本,每秒一行。 文本位于.txt文件中,每行有4个整数

但是当我在DragonFly BSD上编译它时,前一两行在textbox上完美地显示出来,但是程序停止了,并且出现了SIGABRT和SIGSEGV错误

所以我在Windows上编译了相同的代码,它有一个错误:“System.AccessViolationException”异常或类似的错误

我检查了“允许不安全代码”,但结果是一样的

async void DisplayText(string FileName)
{
    string[] Temp = File.ReadAllLines(FileName);
    string[] ScoreBoard = new string[4];

    TextIter Ti = textview.Buffer.StartIter;

    foreach (string Line in Temp)
    {
        ScoreBoard = Line.Split('\t');

        await Task.Delay(1000);

        textview.Buffer.Insert(ref Ti, ScoreBoard[0]);
        textview.Buffer.Insert(ref Ti, "  |  ");
        textview.Buffer.Insert(ref Ti, ScoreBoard[1]);
        textview.Buffer.Insert(ref Ti, "\t");
        textview.Buffer.Insert(ref Ti, ScoreBoard[2]);
        textview.Buffer.Insert(ref Ti, "  |  ");
        textview.Buffer.Insert(ref Ti, ScoreBoard[3]);
        textview.Buffer.Insert(ref Ti, "\n");
    }
}
代码的其他部分工作得很好,但在这一部分中会出现错误

如果我删除“async”和“wait Task.Delay(1000);”,它没有错误,但我希望每秒显示1行

我该如何解决它呢?

Gtk#脾气暴躁,在处理与UI线程(主线程)发生冲突的线程时效果不佳。此外,您不能从辅助线程更新UI(这对于所有图形工具包都很常见)

如果我正确理解了您的问题,您只能使用System.Threading来睡眠一秒钟。问题是,如果你这样做,你的应用程序将在整秒钟内没有响应

解决方案是积极等待,直到第二秒过去。这比等待一秒钟更不准确,但我希望它能满足您的需要

以下是您需要的代码:

    void ActivelyWaitFor(long targetMillis)
    {
        var stopWatch = new System.Diagnostics.Stopwatch();

        stopWatch.Start();

        while( stopWatch.ElapsedMilliseconds < targetMillis ) {
            Gtk.Application.RunIteration();
        }

        stopWatch.Stop();
    }
void ActivelyWaitFor(长targetMillis)
{
var stopWatch=new System.Diagnostics.stopWatch();
秒表。开始();
while(stopWatch.elapsedmillisons
Gtk可以运行一个迭代并返回(Gtk.Application.RunIteration()),这在这里非常方便。我们可以反复调用它,以提供响应性强的用户界面,同时等待时间的流逝

下面是一个窗口的全部代码,它可以完成您需要的任务,以防您对如何使用它有疑问

public class MainWindow: Gtk.Window
{
    public MainWindow()
        :base(Gtk.WindowType.Toplevel)
    {
        this.Build();

        this.DeleteEvent += (o, evt) => Gtk.Application.Quit();
        this.Shown += (o, args) => this.DisplayText();
    }

    void Build()
    {
        this.TextView = new Gtk.TextView();

        this.Add( this.TextView );
    }

    void DisplayText()
    {
        string[] ScoreBoard = new string[4];
        Gtk.TextIter Ti = this.TextView.Buffer.StartIter;
        string[] Temp = {
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
        };

        foreach (string Line in Temp)
        {
            ScoreBoard = Line.Split('\t');

            this.ActivelyWaitFor( 1000 );

            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[0]);
            this.TextView.Buffer.Insert(ref Ti, "  |  ");
            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[1]);
            this.TextView.Buffer.Insert(ref Ti, "\t");
            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[2]);
            this.TextView.Buffer.Insert(ref Ti, "  |  ");
            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[3]);
            this.TextView.Buffer.Insert(ref Ti, "\n");
        }
    }

    void ActivelyWaitFor(long targetMillis)
    {
        var stopWatch = new System.Diagnostics.Stopwatch();

        stopWatch.Start();

        while( stopWatch.ElapsedMilliseconds < targetMillis ) {
            Gtk.Application.RunIteration();
        }

        stopWatch.Stop();
    }

    private Gtk.TextView TextView;
}
公共类主窗口:Gtk.Window
{
公共主窗口()
:基本(Gtk.WindowType.Toplevel)
{
this.Build();
this.DeleteEvent+=(o,evt)=>Gtk.Application.Quit();
this.show+=(o,args)=>this.DisplayText();
}
void Build()
{
this.TextView=new Gtk.TextView();
this.Add(this.TextView);
}
void DisplayText()
{
字符串[]记分板=新字符串[4];
Gtk.TextIter Ti=this.TextView.Buffer.StartIter;
字符串[]临时={
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
};
foreach(临时中的字符串行)
{
记分板=线分割('\t');
这个。主动等待(1000);
this.TextView.Buffer.Insert(ref Ti,ScoreBoard[0]);
this.TextView.Buffer.Insert(ref Ti,“|”);
this.TextView.Buffer.Insert(参考Ti,记分板[1]);
this.TextView.Buffer.Insert(ref Ti,“\t”);
this.TextView.Buffer.Insert(参考Ti,记分板[2]);
this.TextView.Buffer.Insert(ref Ti,“|”);
this.TextView.Buffer.Insert(参考Ti,记分板[3]);
this.TextView.Buffer.Insert(ref Ti,“\n”);
}
}
void ActivelyWaitFor(长目标毫秒)
{
var stopWatch=new System.Diagnostics.stopWatch();
秒表。开始();
while(stopWatch.elapsedmillisons
希望这能有所帮助。

Gtk#脾气暴躁,在处理与UI线程(主线程)发生冲突的线程时效果不佳。此外,您不能从辅助线程更新UI(这对于所有图形工具包都很常见)

如果我正确理解了您的问题,您只能使用System.Threading来睡眠一秒钟。问题是,如果你这样做,你的应用程序将在整秒钟内没有响应

解决方案是积极等待,直到第二秒过去。这比等待一秒钟更不准确,但我希望它能满足您的需要

以下是您需要的代码:

    void ActivelyWaitFor(long targetMillis)
    {
        var stopWatch = new System.Diagnostics.Stopwatch();

        stopWatch.Start();

        while( stopWatch.ElapsedMilliseconds < targetMillis ) {
            Gtk.Application.RunIteration();
        }

        stopWatch.Stop();
    }
void ActivelyWaitFor(长targetMillis)
{
var stopWatch=new System.Diagnostics.stopWatch();
秒表。开始();
while(stopWatch.elapsedmillisons
Gtk可以运行一个迭代并返回(Gtk.Application.RunIteration()),这在这里非常方便。我们可以反复调用它,以提供响应性强的用户界面,同时等待时间的流逝

下面是一个窗口的全部代码,它可以完成您需要的任务,以防您对如何使用它有疑问

public class MainWindow: Gtk.Window
{
    public MainWindow()
        :base(Gtk.WindowType.Toplevel)
    {
        this.Build();

        this.DeleteEvent += (o, evt) => Gtk.Application.Quit();
        this.Shown += (o, args) => this.DisplayText();
    }

    void Build()
    {
        this.TextView = new Gtk.TextView();

        this.Add( this.TextView );
    }

    void DisplayText()
    {
        string[] ScoreBoard = new string[4];
        Gtk.TextIter Ti = this.TextView.Buffer.StartIter;
        string[] Temp = {
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
            "1\t2\t3\t4",
        };

        foreach (string Line in Temp)
        {
            ScoreBoard = Line.Split('\t');

            this.ActivelyWaitFor( 1000 );

            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[0]);
            this.TextView.Buffer.Insert(ref Ti, "  |  ");
            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[1]);
            this.TextView.Buffer.Insert(ref Ti, "\t");
            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[2]);
            this.TextView.Buffer.Insert(ref Ti, "  |  ");
            this.TextView.Buffer.Insert(ref Ti, ScoreBoard[3]);
            this.TextView.Buffer.Insert(ref Ti, "\n");
        }
    }

    void ActivelyWaitFor(long targetMillis)
    {
        var stopWatch = new System.Diagnostics.Stopwatch();

        stopWatch.Start();

        while( stopWatch.ElapsedMilliseconds < targetMillis ) {
            Gtk.Application.RunIteration();
        }

        stopWatch.Stop();
    }

    private Gtk.TextView TextView;
}
公共类主窗口:Gtk.Window
{
公共主窗口()
:基本(Gtk.WindowType.Toplevel)
{
this.Build();
this.DeleteEvent+=(o,evt)=>Gtk.Application.Quit();
this.show+=(o,args)=>this.DisplayText();
}
void Build()
{
this.TextView=new Gtk.TextView();
this.Add(this.TextView);
}
void DisplayText()
{
字符串[]记分板=新字符串[4];
Gtk.TextIter Ti=this.TextView.Buffer.StartIter;
字符串[]临时={
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
“1\t2\t3\t4”,
};
foreach(临时中的字符串行)
{
记分板=线分割('\t');
这个。主动等待(1000);
this.TextView.Buffer.Insert(ref Ti,ScoreBoard[0]);
this.TextView.Buffer.Insert(ref Ti,“|”);
this.TextView.Buffer.Insert(re