gpt4 book ai didi

.net - Windows 窗体线程和事件 - 传递事件的最有效方法?

转载 作者:行者123 更新时间:2023-12-03 13:18:12 27 4
gpt4 key购买 nike

我的表单从随机工作线程上的另一个对象接收异步回调。我一直在使用委托(delegate)将数据传递给主线程(可用于更新屏幕控件),如下所示。性能很糟糕——一旦我达到每秒 500 次更新,程序就会完全锁定。我的 GUI 处理本身不是问题,因为我可以在表单中模拟这种级别的更新并且没有问题。我应该使用更有效的机制将数据从线程传递到线程吗?

delegate void DStatus( MyStatus obj );
DStatus _status; // set to MainThreadOnStatus during construction

// this function only called on form's owner thread
void MainThreadOnStatus( MyStatus obj )
{
// screen updates here as needed
}

// this function called by arbitrary worker threads in external facility
void OnStatus( MyStatus obj )
{
this.BeginInvoke( _status, obj );
}

最佳答案

我不是计时器的忠实拥护者,如果您想要更多事件驱动的方法,请尝试以下操作:

public class Foo
{
private AsyncOperation _asyncOperation = null;
private SendOrPostCallback _notifyNewItem = null;

//Make sure you call this on your UI thread.
//Alternatively you can call something like the AttachUI() below later on and catch-up with
//your workers later.
public Foo()
{
this._notifyNewItem = new SendOrPostCallback(this.NewDataInTempList);
this._asyncOperation = AsyncOperationManager.CreateOperation(this);
}

public void AttachUI()
{
if (this._asyncOperation != null)
{
this._asyncOperation.OperationCompleted();
this._asyncOperation = null;
}

this._asyncOperation = AsyncOperationManager.CreateOperation(this);
//This is for catching up with the workers if they’ve been busy already
if (this._asyncOperation != null)
{
this._asyncOperation.Post(this._notifyNewItem, null);
}
}


private int _tempCapacity = 500;
private object _tempListLock = new object();
private List<MyStatus> _tempList = null;

//This gets called on the worker threads..
//Keeps adding to the same list until UI grabs it, then create a new one.
public void Add(MyStatus status)
{
bool notify = false;
lock (_tempListLock)
{
if (this._tempList == null)
{
this._tempList = new List<MyStatus>(this._tempCapacity);
notify = true;
}

this._tempList.Add(status);
}
if (notify)
{
if (this._asyncOperation != null)
{
this._asyncOperation.Post(this._notifyNewItem, null);
}
}
}

//This gets called on your UI thread.
private void NewDataInTempList(object o)
{
List<MyStatus> statusList = null;
lock (this._tempListLock)
{
//Grab the list, and release the lock as soon as possible.
statusList = this._tempList;
this._tempList = null;
}
if (statusList != null)
{
//Deal with it here at your leasure
}
}
}

我在一个自定义的 Log4Net 记录器中使用了它来收集日志条目并将它们添加到一个绑定(bind)到网格的循环数组中。性能最终表现得非常好。

关于.net - Windows 窗体线程和事件 - 传递事件的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/130132/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com