C#2008 SP1
下面的函数将从另一个线程调用。因此,必须调用控件本身,以便创建它们的正确线程可以更改属性。
但是,因为我有许多需要更新的控件。我真的不想为每一个代表编写所有代表。我在下面做了一个。但是,我认为这是很多代码。无论如何要缩短这个吗?
非常感谢,
public void SetIdleState(string callStatusMsg)
{
this.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call;
this.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall;
this.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold;
this.btnCallAnswer.Enabled = true;
this.btnRedial.Enabled = true;
this.btnEndCallReject.Enabled = false;
this.btnHoldUnhold.Enabled = false;
if (this.statusDisplay1.InvokeRequired)
{
statusDisplay1.Invoke(new UpdateCallStatusDelegate(this.UpdateCallStatus), callStatusMsg);
}
else
{
this.statusDisplay1.CallStatus = callStatusMsg;
}
}
// Delegate for marshalling the call on the correct thread.
private delegate void UpdateCallStatusDelegate(string callStatusMsg);
private void UpdateCallStatus(string callStatusMsg)
{
this.statusDisplay1.CallStatus = callStatusMsg;
}
答案 0 :(得分:1)
如下:
Dispatcher.BeginInvoke(new DispatcherOperationCallback((param) =>
{
this.statusDisplay1.CallStatus = callStatusMsg;
return null;
}), DispatcherPriority.Background, new object[] { null });
}
答案 1 :(得分:1)
我问了一个类似的question 。 Jon Skeet提供的答案是我遇到的最佳方法。相关代码如下。
创建一个静态辅助方法:
public static void InvokeIfNecessary(UIElement element, MethodInvoker action)
{
if (element.Dispatcher.Thread != Thread.CurrentThread)
{
element.Dispatcher.Invoke(DispatcherPriority.Normal, action);
}
else
{
action();
}
}
在您的示例中,您可以将其用作:
InvokeIfNecessary(statusDisplay1, delegate {statusDisplay1.CallStatus = callStatusMsg;});
答案 2 :(得分:1)
以下是我在之前的项目中所做的事情:
我写了一个帮助器静态类。
public static class WorkbenchService
{
private static SynchronizationContext uiContext;
static WorkbenchService()
{
uiContext = WindowsFormsSynchronizationContext.Current;
}
/// <summary>
/// Makes a call GUI threadSafe. WARNING: This method waits for the result of the operation, which can result in a dead-lock when the main thread waits for this thread to exit!
/// </summary>
public static void SafeThreadCall(SendOrPostCallback d, object state)
{
uiContext.Send(d, state);
}
/// <summary>
/// Makes a call GUI thread safe without waiting for the returned value.
/// </summary>
public static void SafeThreadAsyncCall(SendOrPostCallback d, object state)
{
uiContext.Post(d, state);
}
}
然后我就像使用它一样:
WorkbenchService.SafeThreadAsyncCall(delegate {
this.statusDisplay1.CallStatus = "Blah";
this.btnCallAnswer.Text = "hello there";
}, null);
答案 3 :(得分:0)
我找到了最好的方法。并将我的代码转换为此。
希望这有助于其他人。
// Delegate for marshalling the call on the correct thread.
private delegate void SetIdleStateDelegate(string callStatusMsg);
// Set object back to idle state.
public void SetIdleState(string callStatusMsg)
{
if (this.InvokeRequired)
{
this.Invoke(new SetIdleStateDelegate(SetIdleState), callStatusMsg);
}
else
{
this.btnCallAnswer.Text = CATWinSIP_MsgStrings.Call;
this.btnEndCallReject.Text = CATWinSIP_MsgStrings.EndCall;
this.btnHoldUnhold.Text = CATWinSIP_MsgStrings.Hold;
this.btnCallAnswer.Enabled = true;
this.btnRedial.Enabled = true;
this.btnEndCallReject.Enabled = false;
this.btnHoldUnhold.Enabled = false;
}
}